PHP华为快应用华为支付和回调处理
程序员文章站
2024-02-18 15:54:04
...
最近在做华为快应用,所以涉及到了华为支付功能。
快应用发起支付的代码
首先看一下华为快应用提供的参数组装:
下面我们看下实际代码
// 调用快应用里的华为支付
// 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
注意
- 在manifest.json文件的 features属性中增加如下配置: {“name”: “service.pay”}
- 文件必须引入导入模块 import pay from ‘@service.pay’
后端代码
快应用请求发起支付的接口
/*
* 华为支付
* */
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
上一篇: mysql存储过程事务管理简析
推荐阅读