Maison  >  Article  >  développement back-end  >  Exemple de code PHP pour implémenter le paiement de l'application Alipay et la notification asynchrone

Exemple de code PHP pour implémenter le paiement de l'application Alipay et la notification asynchrone

不言
不言original
2018-07-26 11:13:423056parcourir

Le contenu de cet article concerne l'exemple de code d'implémentation du paiement de l'application Alipay et de la notification asynchrone en PHP. Le contenu est très détaillé. Les amis dans le besoin peuvent s'y référer.

J'ai déjà écrit le code d'arrière-plan du paiement pour l'application Alipay. Parlons maintenant de la notification asynchrone :

Personnellement, j'estime que les étapes de la notification asynchrone d'Alipay sont plus simples que celles de WeChat, mais il n'y a pas de pièges. Et encore moins, une seule vérification de signature m'a rendu fou...

Notification asynchrone :

1, confirmez d'abord l'adresse de rappel écrite lorsque payer l'exactitude !!!!!!

2. Recherchez la classe de vérification de signature encapsulée par Alipay, rsaCheckV1 (c'est également dans l'interface app2.0)

3. 🎜>

*4. Vérifiez la commande

Assurez-vous d'abord que l'adresse de rappel inscrite lors du paiement est correcte !!!!!!

Assurez-vous de confirmer l'adresse de rappel Que l'écriture fasse référence à celle où vous avez écrit la vérification de rappel, mettez-la dedans. Ne vous grattez pas la tête lorsque vous cherchez des erreurs

Trouvez la classe de vérification de signature encapsulée. par Alipay, rsaCheckV1 (c'est aussi dans l'interface app2.0)

Voici la classe qu'Alipay a encapsulée :

/** rsaCheckV1 & rsaCheckV2
  * 验证签名
  * 在使用本方法前,必须初始化AopClient且传入公钥参数。
  * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
  **/
 public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') {
  $sign = $params['sign'];
  $params['sign_type'] = null;
  $params['sign'] = null;
  $this->alipayrsaPublicKey = $rsaPublicKeyFilePath;

  return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType);
 }
 public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') {
  $sign = $params['sign'];
  $params['sign'] = null;
  return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType);
 }
 function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') {

  if($this->checkEmpty($this->alipayPublicKey)){

   $pubKey= $this->alipayrsaPublicKey;
   $res = "-----BEGIN PUBLIC KEY-----\n" .
    wordwrap($pubKey, 64, "\n", true) .
    "\n-----END PUBLIC KEY-----";
  }else {
   //读取公钥文件
   $pubKey = file_get_contents($rsaPublicKeyFilePath);
   //转换为openssl格式密钥
   $res = openssl_get_publickey($pubKey);
  }

  ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); 

  //调用openssl内置方法验签,返回bool值
  if ("RSA2" == $signType) {
   $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256);
  } else {
   $result = (bool)openssl_verify($data, base64_decode($sign), $res);
  }

  if(!$this->checkEmpty($this->alipayPublicKey)) {
   //释放资源
   openssl_free_key($res);
  }

  return $result;
 }

Il existe d'autres méthodes. Ces deux méthodes sont confondues. La première doit transmettre le type de signe, mais la seconde ne le fait pas (les deux premières méthodes appelleront la troisième méthode). Un autre point important est que cette méthode extrait elle-même la clé publique de). le fichier. , mais je l'ai transmis directement, j'ai donc légèrement modifié cette méthode pour lui permettre de lire directement la clé publique que j'ai transmise. Cette méthode de vérification de signature renvoie (bool) true ou (bool) false pour déterminer la vérification de la signature. ?

Trois points doivent être notés ici :

1—Faites attention à l'exactitude de la clé publique. Ce qui est également utile, c'est que la clé publique Alipay n'est pas la clé publique que vous avez générée à l'origine.

2— Distinguer la méthode ici et la méthode d'obtention de la clé publique de la méthode de l'interface Alipay elle-même
3—Il est important de faire attention aux commentaires sur la méthode de l'interface elle-même

Paramètres de rappel de vérification

Alipay Les paramètres de rappel sont renvoyés sous forme de post, mais lorsque nous testons, nous pouvons écrire l'url de rappel directement dans la barre d'adresse, puis utiliser le get méthode pour l'accepter, il n'est donc pas nécessaire d'épeler les paramètres, et le résultat est le même (l'URL de rappel peut être enregistrée dans le fichier journal), et lors de la vérification de la signature, tous les paramètres de retour doivent être intacts pour vérifier la signature , et ici vous pouvez simplement recevoir tous les paramètres dont vous avez besoin. Je n'entrerai pas dans plus de détails ici, c'est un problème normal d'acceptation des paramètres. Voici le code que j'utilise pour vérifier le montant de la commande et le numéro du commerçant lors de la vérification des paramètres, pour référence. uniquement (j'utilise tp5) :

public function check($receipt_amount,$buyer_pay_amount,$order_price,$app_id,$seller_email){
  if($receipt_amount !== $order_price || $buyer_pay_amount !== $order_price){
//    echo 1;
   return $this->log('订单支付金额有误!');
  }
  //支付宝支付的所有参数
  $alipay_config = Config::get('alipay_config');
  if($app_id !== $alipay_config['appid']){
//   echo 2;
    return $this->log('商家编号有误!');
  }

  //验证收款商家是否正确
  if($seller_email !== $alipay_config['seller_id']){
//   echo 3;
   return $this->log('收款商家有误!');
  }
  return 'success';
 }

Vérifier les commandes

L'essentiel ici est de vérifier le inventaire. Il est préférable d'utiliser le traitement des transactions ici (bien que votre volume de commandes ne revienne pas nécessairement à ce point), ce qui suit est Voici mon code pour référence seulement (tp5) :

public function index($order_sn='')
 {
  if(isset($_POST['order_sn']) && empty($order_sn)){
   $order_sn = $_POST['order_sn'];
  }

  $table = self::order_info($order_sn);
  if($table == 'failure'){return 'false';}
  $oid = $table['order_id'];
  //通过订单id $oid 查询出订单中物品的id
  $goodsTable = Db::name('goods');
  $allgoods = Db::name("test1")->where('o_id', $oid)->field('g_id,g_num')->select();
  foreach ($allgoods as $k => $v) {
   //事务处理
   $goodsTable->startTrans();//事物开始
   try {
    //判断库存数量
    $goodsTable->query('update test2 set g_num = g_num-' . $v['g_num'] . ' where g_num >= ' . $v['g_num'] . ' and gid =' . $v['g_id']);

   } catch (\Exception $e) {
    $goodsTable->rollBack();//事物回滚
   }

   $goodsTable->commit();// 事物提交
  }

  //修改订单
  $res = Db::name('test3')->where('order_sn',$order_sn)->update(['order_state' => '1','pay_time'=>time()]);
  if($res != 0){
   return 'success';
  }
 }

L'étape suivante consiste à renvoyer le résultat à Alipay. Échec : renvoyer « échec » ;Succès : renvoyer « succès » ;Cela se termine ici.

Aussi, restez calme après. faire une erreur et lors de la recherche de bugs. Ce n'est qu'en recherchant les problèmes de manière rationnelle que vous pourrez trouver le problème plus rapidement (si c'est vraiment le cas). Si cela ne fonctionne pas, accédez au support manuel d'Alipay. Il déboguera votre code pour vous et vous donnera un conclusion similaire. Il vous sera alors beaucoup plus facile d'apporter des modifications :) ).

Enfin, j'espère que tout le monde paiera.

Recommandations associées :

Comment implémenter la fonction de paiement APP d'Alipay en php (code)

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