PHP implementation of wechat enterprise payment to personal change steps

Wechat payment enterprise payment to change function is widely used, such as wechat red packet reward, business settlement, etc. Through enterprise payment to individuals, payment funds will directly enter users' wechat change.

I. opening conditions

 

Payment fund

The enterprise pays the change fund with the balance fund of the merchant number.

According to the account opening situation of the merchant number, there are differences in the actual disbursement account:

◆ by default, the basic account (or balance account) balance of the merchant number is used when the enterprise pays the change. If the merchant number has opened an operation account, the enterprise will pay the change to use the funds in the operation account.

◆ the capital source of the basic account (or other above-mentioned disbursement account) may be the transaction settlement fund (only the basic account) or the capital charged to the account. When the balance of the disbursement account is insufficient, the payment will fail due to insufficient balance.

Payment rules

Payment method

Support API interface or web page operation, and pay to target users.

Identity assignment of payee

◆ specify the payee through APPID+OPENID.

◆ APPID needs to be the APPID when applying for the merchant number or has a binding relationship with the merchant number.

◆ for the access method of OPENID, please refer to: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839

Payment limit

◆ payment for non real name users is not supported

◆ payment to the same real name user, single daily limit 2W/2W

◆ the total payment limit of one merchant on the same day is 100W

Note: the limit 2w and 100w in the above rules are not fully accurate due to the relationship between the calculation rules and risk control strategy, and the amount is only for reference. Please do not rely on this amount for system processing. The actual return and query results of the interface shall prevail, please be aware.

Identity verification of payee

◆ provide the function of verifying the real name for the target user of payment

Query payment status

◆ for the paid records, the enterprise can check the corresponding data through the enterprise payment query, or query the capital flow of the merchant number.

Frequency of payment

◆ by default, the payment to the same user can be made up to 10 times a day, which can be set in the merchant platform API security

Other precautions

◆ the payment amount must be less than or equal to the current available balance of the merchant;

 

II. Interface address

Interface link: https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers

 

Request parameters:

Please refer to the official enterprise payment development document for details

 

1. Basic configuration

 1 //Public account number appid
 2  $data["mch_appid"] = 'appid';
 3 //Merchant number 
 4  $data["mchid"] = '';
 5 //Random string 
 6  $data["nonce_str"] = 'suiji'.mt_rand(100,999); 
 7 //Merchant order number 
 8  $data["partner_trade_no"]=date('YmdHis').mt_rand(1000,9999); 
 9 //Amount the withdrawal amount entered by the user needs to be multiplied by 100  
10  $data["amount"] = $money; 
11 //Enterprise payment description
12  $data["desc"] = 'Enterprise pay to individual change'; 
13 //user openid   
14  $data["openid"] = $openid; 
15 //Do not verify user name  
16  $data["check_name"] = 'NO_CHECK'; 
17 //Obtain IP  
18  $data['spbill_create_ip']=$_SERVER['SERVER_ADDR']; 
19 //Merchant key 
20  $data['key']='';
21 //Merchant certificate API Security certificate Download
22  $data['apiclient_cert.pem']
23  $data['apiclient_key.pem']

 

 

2.PHP code

 1 /**
 2 **Start payment
 3 /
 4  public function userpay(){
 5  $money = 'User input withdrawal amount';
 6  $info['money'] = 'User balance';
 7  if ($this->openid && $money){
 8   if ($money>$info['money'] ){
 9   echo json_encode([
10    'status' => 1,
11    'message' => 'The balance is not enough. Cash withdrawal is not allowed!',
12    'code'=>'The balance is not enough. Cash withdrawal is not allowed!'
13   ]);
14   }elseif ($money<1){
15   echo json_encode([
16    'status' => 2,
17    'message' => 'Withdrawal amount cannot be less than 1 yuan',
18    'code'=>'Withdrawal amount is too low'
19   ]);
20   }else{
21  $openid = $this->openid;
22  $trade_no = date('YmdHis').mt_rand(1000,9999);
23  $res = $this->pay($openid,$trade_no,$money*100,'WeChat cash');
24 
25  //Result printing
26  if($res['result_code']=="SUCCESS"){
27 
28    echo json_encode([
29    'status' => 3,
30    'message' => 'Withdrawal succeeded!',
31    ]);
32   }elseif ($res['err_code']=="SENDNUM_LIMIT"){
33    echo json_encode([
34    'status' => 4,
35    'message' => 'Withdrawal failed!',
36    'code'=>'Only one withdrawal per day',
37    ]);
38   }else{
39    echo json_encode([
40    'status' => 5,
41    'message' => 'Withdrawal failed!',
42    'code'=>$res['err_code'],
43    ]);
44   }
45   }
46  }else{
47   echo json_encode([
48   'status' => 5,
49   'message' => 'Your current wechat account is not detected~',
50 
51   ]);
52  }
53  }

 

 

Payment method

 1 /**
 2 *Payment method
 3 /
 4 public function pay($openid,$trade_no,$money,$desc){
 5  $params["mch_appid"]=''; 
 6  $params["mchid"] = ''; 
 7  $params["nonce_str"]= 'suiji'.mt_rand(100,999); 
 8  $params["partner_trade_no"] = $trade_no;  
 9  $params["amount"]= $money;  
10  $params["desc"]= $desc;  
11  $params["openid"]= $openid;  
12  $params["check_name"]= 'NO_CHECK'; 
13  $params['spbill_create_ip'] = $_SERVER['SERVER_ADDR']; 
14 
15  //Generate signature
16  $str = 'amount='.$params["amount"].'&check_name='.$params["check_name"].'&desc='.$params["desc"].'&mch_appid='.$params["mch_appid"].'&mchid='.$params["mchid"].'&nonce_str='.$params["nonce_str"].'&openid='.$params["openid"].'&partner_trade_no='.$params["partner_trade_no"].'&spbill_create_ip='.$params['spbill_create_ip'].'&key=Merchant key';
17 
18  //md5 encryption to uppercase
19  $sign = strtoupper(md5($str));
20  //Generate signature
21  $params['sign'] = $sign;
22 
23  //Construct XML data
24  $xmldata = $this->array_to_xml($params); //Array to XML
25  $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/prom otion/transfers';
26 
27  //Send post request
28  $res = $this->curl_post_ssl($url, $xmldata); //curl request 
29  if(!$res){
30  return array('status'=>1, 
31    'msg'=>"Server connection failed" );
32  }
33 
34  //Payment result analysis
35  $content = $this->xml_to_array($res); //xml to array
36  return $content;
37  }

 

 

curl request

 1 /**
 2 * curl request
 3 /
 4 public function curl_post_ssl($url, $xmldata,  $second=30,$aHeader=array()){
 5  $ch = curl_init();
 6  //Timeout time
 7  curl_setopt($ch,CURLOPT_TIMEOUT,$second);
 8  curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
 9  //Set up a proxy here, if any
10  //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
11  //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
12  curl_setopt($ch,CURLOPT_URL,$url);
13  curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
14  curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
15 
16  //The default format is PEM, which can be annotated
17  curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
18 //The absolute address can be printed with dirname ( dir ). If it is not the absolute address, 58 errors will be reported
19  curl_setopt($ch,CURLOPT_SSLCERT,' Absolute address/apiclient_cert.pem');
20  curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
21  curl_setopt($ch,CURLOPT_SSLKEY,'Absolute address/apiclient_key.pem');
22  if( count($aHeader) >= 1 ){
23   curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
24  }
25  curl_setopt($ch,CURLOPT_POST, 1);
26  curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
27  $data = curl_exec($ch);
28  if($data){
29  curl_close($ch);
30  return $data;
31  }
32  else {
33  $error = curl_errno($ch);
34  echo "call faild, errorCode:$error\n";
35  die();
36  curl_close($ch);
37  return false;
38  }
39  }

 

 

Generate signature

 1 /**
 2  * array Turn xml
 3  * Used to generate signatures
 4 */
 5 public function array_to_xml($arr){
 6  $xml = "<xml>";
 7  foreach ($arr as $key => $val) {
 8  if (is_numeric($val)) {
 9  $xml .= "<" .$key.">".$val."</".$key.">";
10  } else
11  $xml .= "<".$key."><![CDATA[".$val."]]></".$key.">";
12  }
13  $xml .= "</xml>";
14  return $xml;
15  }
16 
17 /**
18 * xml Convert to array
19 */
20 public function xml_to_array($xml){
21  //Prohibit external references xml entity
22  libxml_disable_entity_loader(true);
23  $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
24  return $values;
25  }

 

The effect is as follows:

Keywords: PHP xml curl less

Added by XzorZ on Mon, 18 Nov 2019 17:08:45 +0200