小游戏支付
微信小游戏支付是通过米大师虚拟支付来完成的,仅支持安卓端。
文档地址:https://developers.weixin.qq.com/minigame/dev/guide/open-ability/virtual-payment.html#开发流程
前提
获取openid
文档地址:developers.weixin.qq.com/minigame/...
获取access_token
文档地址:developers.weixin.qq.com/minigame/...
public function getAccessToken ()
{
$appId = "这里是填小程序appid";
$secret = "这里是填小程序唯一凭证密钥";
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appId . "&secret=" . $secret;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$output = curl_exec($curl);
$res = json_decode($output, true);
return $res['access_token'];
}
1 组装请求参数
文档地址:developers.weixin.qq.com/minigame/...
由支付文档可知必填的参数有哪些,以下是组装好的请求参数:
public function getOrderData ()
{
$postData = [
'openid' => '这里填在前提中已经获取的openid',// 用户唯一标识
'appid' => "这里填小程序appid", // 小游戏appID
'offer_id' => "这里米大师平台上的offer_id", // 米大师分配offer_id
'zone_id' => "1", // 游戏服务器大区
'pf' => 'android', // 平台
'ts' => time(), // 时间
'amt' => 100, // 游戏币
'bill_no' => time(), // 订单号
];
$postData['sig'] = $this->getPaySig($postData,"这里是米大师平台上的AppKey"); // 计算签名
return $postData;
}
getPaySig()
:对请求数据进行签名,具体代码见 1.1。
1.1 签名
/**
* 对请求支付接口的参数进行签名
*
* @param array $postData 请求参数
* @param string $secret 米大师平台上的密钥AppKey
* @return string
*/
public function getPaySig ($postData, $secret, $uri)
{
ksort($postData);
$params = http_build_query($postData) . '&org_loc=/cgi-bin/midas/pay&method=POST&secret=' . $secret;
return hash_hmac('sha256', $params, $secret, false);
}
2 请求米大师扣款
/**
* 请求midas扣款
*
* @param $postData array 请求midas支付接口的数据
* @return mixed
*/
public function postCurlPay(array $postData)
{
// 获取 ACCESS_TOKEN
$access_token = "这里填在前提中获取的access_token";
$url = "https://api.weixin.qq.com/cgi-bin/midas/pay?access_token=". $access_token;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postData, JSON_UNESCAPED_UNICODE));
$output = curl_exec($curl);
return json_decode($output, true);
}
如果请求扣款成功的话,errCode 为 0。这时可以直接对订单支付状态进行更改,因为米大师虚拟支付不像微信支付会有回调通知。
如果 errCode 不为 0,即为失败,如下所示为余额不足:
{
"errcode":90013,
"errmsg":"balance not enough rid: 60bc6834-70212107-35f18c39"
}
3 米大师充值
步骤2中如果 errCode 为 90013,说明游戏币不足,这时可以组装数据返回给前端,由前端去发起游戏币充值请求。
文档地址:developers.weixin.qq.com/minigame/...
/**
* 组装数据返回给前端去请求购买游戏币
*
* @param $postData array 请求米大师扣款的参数
* @return false|mixed
*/
public function purchase($postData)
{
$returnMidasPayData = [
'mode' => 'game',
'env' => 0,
'offerId' => "这里米大师平台上的offer_id",
'currencyType' => 'CNY',
'platform' => 'android',
'buyQuantity' => 100,
'zoneId' => 1,
'postData' => $postData
];
}
这里的 $returnMidasPayData['postData']
不是游戏币充值接口 wx.requestMidasPayment()
需要的,但是米大师充值成功后,会将用户支付状态返回给前端,这时如果支付状态为成功的话,前端可以再拿这个 postData 去请求步骤2的postCurlPay()
,重新发起扣款请求。
如果文章有帮到你的话,别忘了点赞收藏噢 :smile: