Home  >  Article  >  Backend Development  >  PHP code example to implement Alipay app payment and asynchronous notification

PHP code example to implement Alipay app payment and asynchronous notification

不言
不言Original
2018-07-26 11:13:423132browse

The content of this article is to share with you code examples about PHP implementation of Alipay app payment and asynchronous notification. The content is very detailed. Friends in need can refer to it. I hope it can help you.

I have written the payment background code for Alipay app payment before. Now let’s talk about asynchronous notification:

Personally feel that the steps of Alipay’s asynchronous notification are simpler than those of WeChat, but there are no pitfalls. How much less, just one signature verification drove me crazy...

Asynchronous notification:

1, first confirm the callback address written when paying Correctness!!!!!!

2. Find the signature verification class encapsulated by Alipay, rsaCheckV1 (this is also in the app2.0 interface)

3. Verify the callback parameters

*4. Check the order

First make sure the callback address written when paying is correct!!!!!!

Be sure to confirm the callback address Whether the writing refers to the one where you wrote the callback verification, put it in it. Don't scratch your head when you look back for errors.

Find the signature verification class encapsulated by Alipay, rsaCheckV1 (this is also In the app2.0 interface)

This is the class that Alipay has encapsulated:

/** 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;
 }

Also, don’t use this The two methods are confused. The former needs to pass signtype, but the latter does not (the first two methods will call the third method). Another important point is that this method itself extracts the public key from the file, but I passed it directly, so I modified this method slightly so that it can directly read the public key I passed. This signature verification method returns (bool) true or (bool) false to determine whether the signature verification is successful. .

Three points to note here:

1—Pay attention to the correctness of the public key. What’s also useful is that the Alipay public key is not the public key you originally generated
2—Here’s the difference method and the public key acquisition method of the method of the Alipay interface itself
3 - Pay attention to the comments on the interface method itself, it is very important

Verification callback parameters

Alipay callback The parameters are returned in the form of post, but when we test, we can write the callback url directly in the address bar, and then accept it in the get method, so that we don’t have to spell the parameters, and the result is the same (the callback url can be recorded in the log file), and when verifying the signature, all return parameters need to be intact to verify the signature, and here you can just receive whatever parameters you need. I won’t go into details here, it’s normal. Problem with accepting parameters. Here is the code I use to verify the order amount and merchant number when verifying parameters, for reference only (I use 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';
 }

Check Order

The main thing here is to check the inventory. It is best to use transaction processing here (although your order volume may not necessarily return to this point), my code is given below , for reference only (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';
  }
 }

The next step is to return the result to Alipay, failure: return 'failure'; success: return 'success ';It's over here.

Also, be calm after making a mistake and when looking for bugs. Only by looking for problems rationally can you find the problem faster (if it really doesn't work, go to Alipay. With manual support, he will debug your code for you and give you a similar conclusion, and then it will be much easier for you to make changes :) ).

Finally, I hope everyone pays and the callback can be successful!

Related recommendations:

phpHow to implement Alipay’s APP payment function (code)

##

The above is the detailed content of PHP code example to implement Alipay app payment and asynchronous notification. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn