Maison >développement back-end >tutoriel php >Comment écrire un programme de développement d'interface de paiement WeChat en PHP

Comment écrire un programme de développement d'interface de paiement WeChat en PHP

墨辰丷
墨辰丷original
2018-06-01 16:00:565470parcourir

L'interface de paiement WeChat ressemble maintenant lentement à Alipay, qui peut utiliser l'interface API pour implémenter des sites Web ou des applications tiers pour le paiement. Ce qui suit est un programme de développement d'interface de paiement php WeChat et a été testé. Les amis intéressés peuvent s'il vous plaît. reportez-vous à

explication du programme de développement d'interface de paiement php WeChat :

Conditions nécessaires :
appid //obtenues auprès du développeur backend du compte officiel center (Identique à celui dans l'e-mail)

mchid//Obtenu dans l'e-mail

clé//Configuré par le backend du marchand

appsecret //Obtenu dans le Centre de développement de compte officiel
Deux fichiers de certificat, obtenez apiclient_cert.pem dans l'e-mail apiclient_key.pem
Remarques :
Arrière-plan du compte officiel Paiement WeChat-"Configuration du développement-"Ajouter un répertoire de test et testez votre compte WeChat personnel.
Centre des développeurs-"Autorisation de page Web pour obtenir des informations utilisateur de base-" Remplacez-le par votre nom de domaine de test. Sinon, une erreur du paramètre redirect_uri se produira
——————————Suivi à améliorer——————-
La page de paiement WeChat prête à effectuer seule trois opérations dans le arrière-plan :

1. Obtenez openid

//使用jsapi接口
 
 代码如下复制代码
  $jsApi = new JsApi_pub();
 
  //=========步骤1:网页授权获取用户openid============
  //通过code获得openid
  if (!isset($_GET['code']))
  {
    //触发微信返回code码
    $url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
    //echo $url;
    Header("Location: $url");
  }else
  {
    //获取code码,以获取openid
    $code = $_GET['code'];
    $jsApi->setCode($code);
    $openid = $jsApi->getOpenid();
  }

Au début, je a également rencontré des problèmes lors de la première étape et n'a pas pu l'obtenir. openid est lié à certains serveurs. La démo utilise curl pour l'obtenir.
C'est étrange que le curl de mon serveur n'ait pas pu être obtenu. Plus tard, il a été remplacé par file_get_contents et il peut être obtenu normalement.
Mais ce n’est pas la solution. Parce que d'autres opérations curl seront nécessaires plus tard.
J'ai vu un endroit dans la documentation de développement qui nécessitait libcurl 7.20.1 ou supérieur pour les opérations de certificat. Ensuite, j'ai travaillé sur le serveur pour améliorer la version de php curl pour Linux. En fin de compte, je viens de passer à un autre serveur Windows.
Faisons cela pour l'instant et débogueons-le la prochaine fois lorsque nous aurons besoin de l'utiliser.

Deuxième étape : Obtenir et payer l'identifiant du numéro de commande
Le code est le suivant

$unifiedOrder = new UnifiedOrder_pub();
   
  //var_dump($unifiedOrder);
  //设置统一支付接口参数
  //设置必填参数
  //appid已填,商户无需重复填写
  //mch_id已填,商户无需重复填写
  //noncestr已填,商户无需重复填写
  //spbill_create_ip已填,商户无需重复填写
  //sign已填,商户无需重复填写
  $unifiedOrder->setParameter("openid","$openid");//商品描述
  $unifiedOrder->setParameter("body","贡献一分钱");//商品描述
  //自定义订单号,此处仅作举例
  $timeStamp = time();
  $out_trade_no = WxPayConf_pub::APPID."$timeStamp";
  $unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商户订单号 
  $unifiedOrder->setParameter("total_fee","1");//总金额
  $unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址 
  $unifiedOrder->setParameter("trade_type","JSAPI");//交易类型
  //非必填参数,商户可根据实际情况选填
  //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号 
  //$unifiedOrder->setParameter("device_info","XXXX");//设备号 
  //$unifiedOrder->setParameter("attach","XXXX");//附加数据 
  //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
  //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间 
  //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记 
  //$unifiedOrder->setParameter("openid","XXXX");//用户标识
  //$unifiedOrder->setParameter("product_id","XXXX");//商品ID
 
 
  $prepay_id = $unifiedOrder->getPrepayId();
   
  //echo 'prepay_id:';
  var_dump($prepay_id);

Cette étape a également rencontré de nombreux problèmes.
Tout d'abord, il est difficile de tester le paiement WeChat, et il ne peut être testé que dans WeChat. J'utilise simplement mon téléphone pour glisser.
Deuxièmement, il n'est pas facile d'utiliser var_dump pour le débogage. L'impression de certains fichiers au format XML affiche uniquement la longueur des caractères, pas le contenu. Je l'ai donc écrit sous forme de log pour le débogage sur le serveur. Le code du log :
Le code est le suivant

// 打印log
  function log_d($word) 
  {
    $log_name="./logd.log";//log文件路径
    $fp = fopen($log_name,"a");
    flock($fp, LOCK_EX) ;
    fwrite($fp,"执行日期:".strftime("%Y-%m-%d-%H:%M:%S",time())."n".$word."nn");
    flock($fp, LOCK_UN);
    fclose($fp);
  }

Utiliser $. dans WxPayPubHelper.php dans la démo, this->log_d(xxx);
Au début, j'avais toujours des erreurs car les mchid et appid qui m'étaient donnés ne correspondaient pas. . Ils m'ont donné un mauvais numéro de compte. Au début, je ne savais pas essayer au hasard. Pour cette étape de débogage, vous pouvez voir le code d'erreur dans var_dump($this->result); dans getPrepayId().

Étape 3 : Générez le code js du front-end de paiement et mettez-le sur la page Web :
Le code est le suivant

$jsApi->setPrepayId($prepay_id);
 
$jsApiParameters = $jsApi->getParameters();

——————-Cliquez pour payer————————-

J'en ai rencontré un autre problème dans cette partie :
android renvoie "System: Access_denied", ios renvoie "access_control:not_allowed"
J'ai beaucoup cherché sur Baidu. En fait, je vois cette chose depuis longtemps et je ne l'ai jamais remarqué !
La page qui initie la demande d'autorisation doit être une page du répertoire d'autorisation et ne peut pas exister dans un sous-répertoire. Sinon, une erreur sera renvoyée
J'ai placé le fichier de paiement dans /domain name/pay/demo/
Au début, j'ai continué jusqu'à la fin de /domain name/pay/ et j'ai pensé que c'était suffisant. Supporte les sous-répertoires, mais le résultat n'est pas possible ! .
————————Regardez enfin l'image ci-dessous————

wxpay1
wxpay3
wxpay2

—— ————xmljs en cours——————–
Identifiant d'ordre de génération et de paiement à soumettre :
Le code est le suivant

<xml>
 <openid><![CDATA[ou9dHt0L8qFLI1foP-kj5x1mDWsM]]></openid>
 <body><![CDATA[贡献一下]]></body>
 <out_trade_no><![CDATA[wx88888888888888881414411779]]></out_trade_no>
 <total_fee>1</total_fee>
 <notify_url><![CDATA[http://shanmao.me/wxpay/notify_url.php]]></notify_url>
 <trade_type><![CDATA[JSAPI]]></trade_type>
 <appid><![CDATA[wx8888888888888888]]></appid>
 <mch_id>10012345</mch_id>
 <spbill_create_ip><![CDATA[61.50.221.43]]></spbill_create_ip>
 <nonce_str><![CDATA[60uf9sh6nmppr9azveb2bn7arhy79izk]]></nonce_str>
 <sign><![CDATA[2D8A96553672D56BB2908CE4B0A23D0F]]></sign>
</xml>

Le retour est correct après soumission, qui inclut perpay_id :

<xml>
 <return_code><![CDATA[SUCCESS]]></return_code> 
 <return_msg><![CDATA[OK]]></return_msg> 
 <appid><![CDATA[wx8888888888888888]]></appid> 
 <mch_id><![CDATA[10012345]]></mch_id> 
 <nonce_str><![CDATA[Be8YX7gjCdtCT7cr]]></nonce_str> 
 <sign><![CDATA[885B6D84635AE6C020EF753A00C8EEDB]]></sign> 
 <result_code><![CDATA[SUCCESS]]></result_code> 
 <prepay_id><![CDATA[wx201410272009395522657a690389285100]]></prepay_id> 
 <trade_type><![CDATA[JSAPI]]></trade_type> 
</xml>

JS pour générer le paiement :

{
  "appId": "wx8888888888888888",
  "timeStamp": "1414411784",
  "nonceStr": "gbwr71b5no6q6ne18c8up1u7l7he2y75",
  "package": "prepay_id=wx201410272009395522657a690389285100",
  "signType": "MD5",
  "paySign": "9C6747193720F851EB876299D59F6C7D"
}

Notification XML renvoyée après un paiement réussi :

<xml><appid><![CDATA[wx8888888888]]></appid>
<bank_type><![CDATA[CCB_DEBIT]]></bank_type>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<mch_id><![CDATA[1011111]]></mch_id>
<nonce_str><![CDATA[38gt0ffgsvfsdfsdfbt1981duv63p7]]></nonce_str>
<openid><![CDATA[o4p3SjfdsfdsfdsdCE5Y2XHw4]]></openid>
<out_trade_no><![CDATA[wx4b56d1fsdfdsf416643247]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[356EfsdfdsfsdsfE69509EDA344]]></sign>
<sub_mch_id><![CDATA[10018826]]></sub_mch_id>
<time_end><![CDATA[20141122160122]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[100715001020fsdfsd1220006123174]]></transaction_id>
</xml>

Résumé : Ce qui précède est le résumé de cet article Tout le contenu, j'espère qu'il sera utile à l'étude de chacun.

Recommandations associées :

phpUne façon simple de calculer l'âge

php Fonction de conversion de temps personnalisée

phpExemples de technologie d'interface et explications détaillées avec images et textes

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!

Déclaration:
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