欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PHP华为快应用华为支付和回调处理

程序员文章站 2024-02-18 15:54:04
...

最近在做华为快应用,所以涉及到了华为支付功能。

快应用发起支付的代码

首先看一下华为快应用提供的参数组装:
PHP华为快应用华为支付和回调处理

下面我们看下实际代码

// 调用快应用里的华为支付
// https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-api-pay
payHuawei() {
    let that = this;
    let buy_data = that.buy_list_data[that.default_chose];
    let body = buy_data.product;
    let detail = buy_data.detail;
    let total_fee = buy_data.price * 100;
    let month = '';
    let timestamp = new Date().getTime();
    let sign = that.$app.$def.md5Fun(body + detail + total_fee + timestamp + month + that.reward);
    let channel = that.$app.$def.CHANNEL;
    let payData = {
        "fee": total_fee, "payfee_vip": 0, "detail": detail, "product": body,
        "timestamp": timestamp, "reward": that.reward, "month": "", "bid": 0,
        "sign": sign, 'channel': channel,
    };
    that.$app.$def.get_fetch(that.$app.$def.config.extend.huaweiPay, payData, function (data) {
        if (data.status === "success") {
            data = data.data;
            pay.pay({
                orderInfo: {
                    "amount": data.amount,     //商品金额
                    "applicationID": that.$app.$def.config.extend.HUAWEI_APPID,    //应用ID,在华为开发者联盟上获取的APP ID 
                    "productDesc": data.productDesc,
                    "productName": data.productName,
                    "serviceCatalog": data.serviceCatalog,    //游戏设置为"X6",应用设置为"X5" 
                    "merchantId": that.$app.$def.config.extend.HUAWEI_PAYID,    //华为开发者联盟上申请支付服务获取的“支付ID“
                    "merchantName": data.merchantName,    //商户名称
                    "sign": data.sign,    //签名
                    "requestId": data.requestId,    //在支付前生成,用于唯一标识一次支付请求。支付平台在服务器回调接口中会原样返回requestId的值 
                    "urlVer": data.urlVer,    //固定值为2
                    "sdkChannel": data.sdkChannel,    //游戏设置为3,应用设置为1
                    "publicKey": that.$app.$def.config.extend.HUAWEI_PUBLIC_KEY,    //华为开发者联盟上申请支付服务获取的“支付公钥”
                },
                success: function (ret) {
                    isOn = 0;
                    that.$app.$def.goUrl('My/Buy/Status?pay=success&orderId=' + ret.requestId)
                },
                fail: function (erromsg, errocode) {
                    isOn = 0;
                    that.$app.$def.goUrl('My/Buy/Status?pay=fail')
                }
            })
        } else {
            isOn = 0;
            that.$app.$def.showToastFun(data.msg);
        }
    });
},

通过上面的代码,能看出是先通过请求后端接口,获取数据之后,然后使用快应用的内置方法发起支付 pay.pay;

具体可以参数官方文档:
https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-api-pay#h1-1577150427242-0

注意

  1. 在manifest.json文件的 features属性中增加如下配置: {“name”: “service.pay”}
  2. 文件必须引入导入模块 import pay from ‘@service.pay’
    PHP华为快应用华为支付和回调处理

后端代码

快应用请求发起支付的接口

/*
 * 华为支付 
 * */
 public function huawei(){
     $uid = $this->uid;
     if (!$uid){
         return_json_data(-99,'请先登录');
     }
     $userInfo = $this->userInfo;

     $total_fee = I('fee','intval',0);					//订单总金额 单位 分
     $total_fee_vip = I('payfee_vip','intval',0);		 //套餐 VIP订单总金额 单位分
     $detail = I('detail','trim','购买奇热小说书币'); 	//商品详情
     $body = I('product','trim','奇热小说书币');		//商品描述
     $sign = I('sign','trim,addslashes','');			//APP与应用服务器之间的数据签名
     $timestamp = I('timestamp','trim,addslashes','');	//时间戳
     $reward = I('reward','intval',2);;				//支付类型  1打赏订单  0购买VIP订单 2书币订单 3首充
     $month = I('month','trim,addslashes','');			//购买月份数
     $bid = I('bid','intval',0);		 	//小说bid(表示用户在该小说页购买的书币,在我的页面购买的设为0)
     $payid = 66;
     $channel = I('channel','intval',0);    
     $detail = str_replace("+",'和',$detail);  // 替换特殊字符

     $sign_ = md5($body.$detail.$total_fee.$timestamp.$month.$reward.APP_KEY);  
     if($sign_ !== $sign){ 
         return_json_data(-16,'签名错误');
     }

     // 写入订单
     $orderId = 'hwapp'.$this->uid.date("mdHis").rand(2000,8000);  

     $data = [
         // 2.0版本
         'merchantId' => "890086000102059940",  // 商户ID,来源于开发者联盟的“支付ID”
         'applicationID' => "101458737", // 应用ID,来源于开发者联盟
         'merchantName' => "奇热小说", // 商户名称,必填,不参与签名。开发者注册的公司名称
         'requestId' => $orderId,	// 商户自己的订单号
         'amount' =>  sprintf("%.2f",$total_fee/100), // 金额
         'url' => $this->notify_host.'/Fastapp/notify/huawei',  // 支付回调地址
         'productName' => $body, 'productDesc' => $detail,   //商品描述
         'sdkChannel' => 1, 'serviceCatalog' => "X5",
         'urlVer' => "2",   // 回调接口版本号
     ];

     // 签名
     $private_key_path = (getcwd()).'/fastapp_huawei_cert/private.pem'; // 私钥文件路径
     $data['sign'] = $this->huaweRsaSign($data,$private_key_path);
     return_json_data(1,'ok',$data);
 }

华为RSA签名

/**
 * 华为RSA签名 
 * @param array $data 参与签名的参数
 * @param string $private_key_path  私钥路径
 * @return bool|string
 */
private function huaweRsaSign($data=[], $private_key_path='') {
    if(empty($data) && !is_array($data)){
        return false;
    }
    $noSignData = [
        'amount'=>$data['amount'],  // 商品金额 请保留小数点后两位,如20.00
        'applicationID'=>$data['applicationID'],  // 应用ID,在华为开发者联盟上获取的APP ID。
//            'country'=>'CNY',    //币种, 暂时不需要
//            'currency'=>'CN',   // 国家码 暂时不需要
        'merchantId'=>$data['merchantId'],    // 商户ID  来源:在华为开发者联盟上获取的“支付ID”
        'productDesc'=>$data['productDesc'],  // 商品描述
        'productName'=>$data['productName'],  // 商户对商品的自定义名称
        'requestId'=>$data['requestId'],      // 商户订单号
        'sdkChannel'=>$data['sdkChannel'],    // 支付结果回调地址 。
//            'url'=>$data['url'],                  //  暂时不需要
//            'urlVer'=>$data['urlVer'],            // 暂时不需要
    ];
    ksort($noSignStr);
    $noSignStr = "";
    foreach ($noSignData as $k => $v){
        $noSignStr .= $k . '=' . $v . '&';
    }
    $noSignStr = substr($noSignStr, 0, strlen($noSignStr)-1);
    if(get_magic_quotes_gpc()){
        $noSignStr = stripslashes($noSignStr);
    }

    // 开始签名
    $priKey = file_get_contents($private_key_path);
    $res = openssl_get_privatekey($priKey);
    $sign = '';
    openssl_sign($noSignStr, $sign, $res, OPENSSL_ALGO_SHA256);
    openssl_free_key($res);
    //base64编码
    $sign = base64_encode($sign);
    return $sign;
}

支付回调

/* 华为支付回调  */
public function huawei(){
    header("Content-Type: application/json; charset=utf-8");
    ksort($_POST);  
    $sign = $_POST['sign'];
    $form = $_POST;
    unset($form['sign']);
    unset($form['signType']);
    if(empty($sign)){
        echo "{\"result\":1}"; 
        return;
    }

    $content = "";
    $i = 0;
    foreach($form as $key=>$value){
        if($key != "sign" && $key != "signType"){
            $content .= ($i == 0 ? '' : '&').$key.'='.$value;
        }
        $i++;
    }
    $filename = (getcwd()).'/qrxs_fastapp_huawei_cert/public.pem';
    $pubKey = @file_get_contents($filename);
    $openssl_public_key = @openssl_get_publickey($pubKey);
    if(!file_exists($filename) || empty($openssl_public_key)){
        echo "{\"result\" : 1 }";;
        return;
    }
    $ok = @openssl_verify($content,base64_decode($sign), $openssl_public_key, 'SHA256');
    @openssl_free_key($openssl_public_key);

    if($ok && $_POST['result'] == 0){
        //支付成功处理业务
        $result = "0"; 
        $orderId = $_POST['requestId']; // 商户自己的订单号
        $trade_no = $_POST['orderId'];  // 华为的交易单号
        
    }else{
        $result = "1";
    }
    $res = "{ \"result\": $result} ";
    echo $res;
}

参考官方文档:https://developer.huawei.com/consumer/cn/doc/development/HMS-References/wallet-api-server-callback-1

相关标签: PHP 快应用 php