Alipay アプリの支払いと非同期通知を実装するための PHP コード例

不言
リリース: 2023-04-03 12:48:02
オリジナル
3133 人が閲覧しました

この記事の内容は、PHP で Alipay アプリ決済と非同期通知を実装するためのコード例を共有することです。内容は非常に詳細です。困っている友人は参考にしてください。お役に立てれば幸いです。

以前、Alipay アプリ決済のバックグラウンド コードを作成しました。次に、非同期通知について話しましょう:

個人的には、Alipay の非同期通知の手順は WeChat の非同期通知の手順よりも簡単だと感じていますが、ましてや、たった 1 回の署名検証で気が狂いそうになった...

非同期通知:

1、まず、支払い時に書き込まれたコールバック アドレスを確認します。 !!!!!!

2. Alipay によってカプセル化された署名検証クラス、rsaCheckV1 を見つけます (これは app2.0 インターフェイスにもあります)

3. コールバック パラメーターを確認します

*4. 注文を確認します

まず、支払い時に記入されたコールバック アドレスが正しいことを確認してください!!!!!!

コールバックを必ず確認してくださいアドレス 記述がコールバック検証を書いた場所を参照しているかどうか、その中に入れてください。エラーを振り返ったときに頭をかかないでください。

Alipay によってカプセル化された署名検証クラスを見つけます、rsaCheckV1 (これも app2.0 インターフェイスにあります)

これは、Alipay がカプセル化したクラスです:

/** 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;
 }
ログイン後にコピー

また、これは使用しないでください 2 つのメソッドは混同されています。前者は署名タイプを渡す必要がありますが、後者は渡しません (最初の 2 つのメソッドは 3 番目のメソッドを呼び出します)。もう 1 つの重要な点は、このメソッド自体が公開キーを抽出することです。この署名検証メソッドは、署名検証が成功したかどうかを決定するために (bool) true または (bool) false を返します。 .

ここで注意すべき 3 つの点:

1 - 公開キーの正確さに注意してください。また、役に立つのは、Alipay 公開キーが最初に生成した公開キーではないことです
2—Alipay インターフェース自体のメソッドの差分メソッドと公開キー取得メソッドは次のとおりです。
3 - インターフェースメソッド自体のコメントに注意してください。非常に重要です。

検証コールバック パラメータ

Alipay コールバック パラメータはポストの形式で返されますが、テスト時にはアドレス バーにコールバック URL を直接書き込み、get メソッドを使用してそれを受け入れることができます。パラメーターを綴る必要はなく、結果は同じです (コールバック URL はログ ファイルに記録できます)。署名を検証する場合、署名を検証するにはすべての戻りパラメーターがそのままである必要があり、ここで次のようにすることができます。必要なパラメータを受け取るだけです。ここでは詳細には触れませんが、これは正常です。パラメータの受け入れに関する問題があります。参考までに、パラメータを検証するときに注文金額と販売者番号を検証するために使用するコードを示します (私は 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

ここでの主なことは在庫を確認することです。トランザクションを使用するのが最善です。ここでの処理 (ただし、注文量が必ずしもこの時点に戻るとは限りません)。参考までに、私のコードを以下に示します (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';
  }
 }
ログイン後にコピー

次のステップは結果を Alipay に返すことです、失敗: return 'failure'; success: return 'success ';ここで終わりです。

また、間違いを犯した後やバグを探すときは冷静になってください。問題について合理的に考えて、より早く問題を見つけることができますか (本当にうまくいかない場合は、Alipay にアクセスしてください。手動サポートがあれば、担当者がコードをデバッグし、同様の結論を示してくれます。そうすれば、より簡単に解決できるでしょう)変更を加えます :) ).

最後に、全員が支払いをしてコールバックが成功することを願っています!

関連する推奨事項:

phpAlipay の APP 支払い機能を実装する方法(コード)

##

以上がAlipay アプリの支払いと非同期通知を実装するための PHP コード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート