Implémentation PHP de l'analyse des cas de paiement APP WeChat

php中世界最好的语言
Libérer: 2023-03-26 18:40:01
original
1594 Les gens l'ont consulté

Cette fois, je vais vous présenter une analyse de cas de mise en œuvre du paiement WeChat dans APP avec PHP. Quelles sont les précautions pour la mise en œuvre du paiement WeChat dans APP avec PHP. Voici un cas pratique, jetons un coup d'œil. .

1. L'arrière-plan PHP génère un ordre de transaction de prépaiement, renvoie l'ID de réponse de transaction de prépaiement correct, puis appelle le paiement dans l'APP

Document officiel :https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

Stitch WeChat selon les besoins le document Paramètres, plusieurs méthodes sont nécessaires ici, allez directement dans le code !

Les paramètres transmis à WeChat doivent être assemblés au format xml et envoyés sous forme de tableau de paramètres !

public function ToXml($data=array())
 {
 if(!is_array($data) || count($data) <= 0)
 {
  return &#39;数组异常&#39;;
 }
 $xml = "<xml>";
 foreach ($data as $key=>$val)
 {
  if (is_numeric($val)){
  $xml.="<".$key.">".$val."</".$key.">";
  }else{
  $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  }
 }
 $xml.="</xml>";
 return $xml;
 }
Copier après la connexion

2 . Générez une chaîne aléatoire, paramètres requis par WeChat ! Il existe de nombreuses méthodes ici, tout dépend de vos loisirs

function rand_code(){
 $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//62个字符
 $str = str_shuffle($str);
 $str = substr($str,0,32);
 return $str;
}
Copier après la connexion

3 C'est une étape importante pour WeChat. ! Générez une signature

private function getSign($params) {
 ksort($params); //将参数数组按照参数名ASCII码从小到大排序
 foreach ($params as $key => $item) {
  if (!empty($item)) {  //剔除参数值为空的参数
  $newArr[] = $key.'='.$item; // 整合新的参数数组
  }
 }
 $stringA = implode("&", $newArr);  //使用 & 符号连接参数
 $stringSignTemp = $stringA."&key="."************************"; //拼接key
 // key是在商户平台API安全里自己设置的
 $stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密
 $sign = strtoupper($stringSignTemp); //将所有字符转换为大写
 return $sign;
 }
Copier après la connexion

4. Transmettez les paramètres à WeChat et générez une commande de pré-paiement ! Recevez les données renvoyées par WeChat et renvoyez-les à l'APP. paiement ! Pour les paramètres requis sur l'APP, voir la documentation WeChat : https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2

public function wx_pay() {
 $nonce_str = $this->rand_code(); //调用随机字符串生成方法获取随机字符串
 $data['appid'] ='wxdbc5dc*******'; //appid
 $data['mch_id'] = '1493*****' ; //商户号
 $data['body'] = "APP支付测试";
 $data['spbill_create_ip'] = $_SERVER['HTTP_HOST']; //ip地址
 $data['total_fee'] = 1;    //金额
 $data['out_trade_no'] = time().mt_rand(10000,99999); //商户订单号,不能重复
 $data['nonce_str'] = $nonce_str;   //随机字符串
 $data['notify_url'] = 'http://xxx.xxx.com/wx_notify'; //回调地址,用户接收支付后的通知,必须为能直接访问的网址,不能跟参数
 $data['trade_type'] = 'APP'; //支付方式
 //将参与签名的数据保存到数组 注意:以上几个参数是追加到$data中的,$data中应该同时包含开发文档中要求必填的剔除sign以外的所有数据
 $data['sign'] = $this->getSign($data); //获取签名
 $xml = $this->ToXml($data);  //数组转xml
 //curl 传递给微信方
 $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
 //header("Content-type:text/xml");
 $ch = curl_init();
 curl_setopt($ch,CURLOPT_URL, $url);
 if(stripos($url,"https://")!==FALSE){
  curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
 } else {
  curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
  curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
 }
 //设置header
 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
 curl_setopt($ch, CURLOPT_HEADER, FALSE);
 //要求结果为字符串且输出到屏幕上
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
 //设置超时
 curl_setopt($ch, CURLOPT_TIMEOUT, 30);
 curl_setopt($ch, CURLOPT_POST, TRUE);
 //传输文件
 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
 //运行curl
 $data = curl_exec($ch);
 //返回结果
 if($data){
  curl_close($ch);
  //返回成功,将xml数据转换为数组.
  $re = $this->FromXml($data);
  if($re['return_code'] != 'SUCCESS'){
  json("201",'签名失败');
  }
  else{
  //接收微信返回的数据,传给APP!
  $arr =array(
   'prepayid' =>$re['prepay_id'],
   'appid' => 'wxdbc5dc*****',
   'partnerid' => '14937****',
   'package' => 'Sign=WXPay',
   'noncestr' => $nonce_str,
   'timestamp' =>time(),
  );
  //第二次生成签名
  $sign = $this->getSign($arr);
  $arr['sign'] = $sign;
  json('200','签名成功',$arr);
  }
 } else {
  $error = curl_errno($ch);
  curl_close($ch);
  json('201',"curl出错,错误码:$error");
 }
 }
Copier après la connexion

5. Convertissez les données XML en un tableau et utilisez-les lors de la réception des données renvoyées par WeChat Go to.

public function FromXml($xml)
 {
 if(!$xml){
  echo "xml数据异常!";
 }
 //将XML转为array
 //禁止引用外部xml实体
 libxml_disable_entity_loader(true);
 $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
 return $data;
 }
Copier après la connexion

2. Une fois le paiement APP réussi, l'adresse de rappel que vous avez renseigné sera appelé

Pour plus de détails sur les paramètres de retour, veuillez consulter la documentation WeChat :https://pay.weixin.qq.com/wiki/doc/api/. app/app.php?chapter=9_7&index=3

// 微信支付回调
 function wx_notify(){
  //接收微信返回的数据数据,返回的xml格式
  $xmlData = file_get_contents('php://input');
  //将xml格式转换为数组
  $data = $this->FromXml($xmlData);
  //用日志记录检查数据是否接受成功,验证成功一次之后,可删除。
  $file = fopen('./log.txt', 'a+');
  fwrite($file,var_export($data,true));
  //为了防止假数据,验证签名是否和返回的一样。
  //记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。
  $sign = $data['sign'];
  unset($data['sign']);
  if($sign == $this->getSign($data)){
  //签名验证成功后,判断返回微信返回的
  if ($data['result_code'] == 'SUCCESS') {
  //根据返回的订单号做业务逻辑
  $arr = array(
   'pay_status' => 1,
   );
  $re = M('order')->where(['order_sn'=>$data['out_trade_no']])->save($arr);
  //处理完成之后,告诉微信成功结果!
  if($re){
   echo '<xml>
  <return_code><![CDATA[SUCCESS]]></return_code>
  <return_msg><![CDATA[OK]]></return_msg>
  </xml>';exit();
  }
  }
  //支付失败,输出错误信息
  else{
  $file = fopen('./log.txt', 'a+');
  fwrite($file,"错误信息:".$data['return_msg'].date("Y-m-d H:i:s"),time()."\r\n"); 
  }
 }
 else{
  $file = fopen('./log.txt', 'a+');
  fwrite($file,"错误信息:签名验证失败".date("Y-m-d H:i:s"),time()."\r\n"); 
  }
}
Copier après la connexion

Ici, le processus de paiement de l'APP WeChat est terminé avec succès ! Merci pour votre soutien !

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Analyse de l'utilisation du cas d'utilisation du chiffrement, du déchiffrement et de l'interface de développement RSA de PHP

Analyse du cas d'utilisation des connexions longues PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!