微信小程序商城如何接入微信支付的功能?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序商城如何接入微信支付的功能?相关的知识,希望对你有一定的参考价值。
微信小程序商城接入微信支付的步骤:1、申请微信支付;
2、获取商户号、设置32位API秘钥、下载证书;
3、将步骤2的参数填入小程序商城后台。
完成对接。 参考技术A 微信小程序商城
首先要申请微信公众号认证通过,小程序才能对接微信。
然后申请微信支付
按照提示一步步获取商户号,设置32位API秘钥,下载证书等。
都会有提示每一步要做什么。 参考技术B 很简单,申请一个微信商户,然后把你这个账号的商户号和密匙按要求填到后台就算是对接完成了。 参考技术C 你只要打开微信支付功能,自然就会把钱支付给别人。 参考技术D 可以自己申请一个商户号,支付费率会比较高,一般是0.6%。也可以找微信支付的服务商,比如禾店科技,服务商申请的话,支付费率一般在0.38%。
商户号申请好以后,和自己的小程序对接就可以了。
Thinkphp5.1微信小程序支付
参考技术A 研究了好几天,坑也遇到了,也百度了很久现在终于做完了,给大家分享出来,我这个也是参考别人写的。有不明白的朋友可以问我
public function unifiedorder($order_no, $openid, $total_fee, $attach, $order_id, $user_id)
// 当前时间
$time = time();
// 生成随机字符串
$nonceStr = md5($time . $openid);
// API参数
$params = [
'appid' => $this->appid, //微信分配的小程序id
'attach' => $attach, //附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
'body' => '会员卡', //募捐描述
'mch_id' => $this->mchid, //微信支付分配的商户号
'nonce_str' => $nonceStr, //随机字符串,32位以内
'notify_url' => $this->notify_url, // base_url() . 'notice.php?s=/task/notify/order/wxapp_id/'.$wxapp_id, // 异步通知地址
'openid' => $openid, //用户标识;trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。
'out_trade_no' => $order_no, //商户账单号
'spbill_create_ip' => \request()->ip(), //终端IP;支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
'total_fee' => (int)$total_fee * 100, // 价格:单位分 // 价格:单位分
'trade_type' => 'JSAPI', //交易类型
];
// 生成签名
$params['sign'] = $this->makeSign($params); //这个地方最坑,需要的是配置 1、appid和商户号必须是绑定的状态
// 请求API
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$result = $this->post($url, $this->toXml($params));
$prepay = $this->fromXml($result);
//添加preapay_id
$data = [
'user_id' => $user_id,
'order_id' => $order_id,
'attach' => json_encode($attach),
'prepay_id' => $prepay['prepay_id'],
];
(new AppleWxPrepay())->addInfo($data);
// 请求失败
if ($prepay['return_code'] === 'FAIL')
return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['return_msg']];
if ($prepay['result_code'] === 'FAIL')
return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['err_code_des']];
// 生成 nonce_str 供前端使用
$paySign = $this->makePaySign($params['nonce_str'], $prepay['prepay_id'], $time);
return [
'prepay_id' => $prepay['prepay_id'],
'nonceStr' => $nonceStr,
'timeStamp' => (string)$time,
'paySign' => $paySign
];
/**
* 生成签名
* @param $values
* @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
private function makeSign($values)
//签名步骤一:按字典序排序参数
ksort($values);
$string = $this->toUrlParams($values);
//签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->apikey;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
/**
* 格式化参数格式化成url参数
* @param $values
* @return string
*/
private function toUrlParams($values)
$buff = '';
foreach ($values as $k => $v)
if ($k != 'sign' && $v != '' && !is_array($v))
$buff .= $k . '=' . $v . '&';
return trim($buff, '&');
/**
* 模拟POST请求
* @param $url
* @param array $data
* @param bool $useCert
* @param array $sslCert
* @return mixed
*/
public function post($url, $data = [], $useCert = false, $sslCert = [])
$header = [
'Content-type: application/json; charset=UTF8'
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
if ($useCert == true)
// 设置证书:cert 与 key 分别属于两个.pem文件
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
$result = curl_exec($curl);
curl_close($curl);
return $result;
/**
* 输出xml字符
* @param $values
* @return bool|string
*/
private function toXml($values)
if (!is_array($values) || count($values) <= 0)
return false;
$xml = "<xml>";
foreach ($values as $key => $val)
if (is_numeric($val))
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
else
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
$xml .= "</xml>";
return $xml;
/**
* 将xml转为array
* @param $xml
* @return mixed
*/
private function fromXml($xml)
// 禁止引用外部xml实体
libxml_disable_entity_loader(true);
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
/**
* 生成paySign
* @param $nonceStr
* @param $prepay_id
* @param $timeStamp
* @return string
*/
private function makePaySign($nonceStr, $prepay_id, $timeStamp)
$data = [
'appId' => $this->appid,
'nonceStr' => $nonceStr,
'package' => 'prepay_id=' . $prepay_id,
'signType' => 'MD5',
'timeStamp' => $timeStamp,
];
// 签名步骤一:按字典序排序参数
ksort($data);
$string = $this->toUrlParams($data);
// 签名步骤二:在string后加入KEY
$string = $string . '&key=' . $this->apikey;
// 签名步骤三:MD5加密
$string = md5($string);
// 签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
/*********************************微信回调**********************/
public function getNotify()
if (!$xml = file_get_contents('php://input'))
$this->returnCode(50000001, 'Not found DATA');
// 将服务器返回的XML数据转化为数组
$data = $this->fromXml($xml);
$payLog = new ApplePayLog();
// 记录日志
$payLog->addInfo(['content'=>json_encode($xml)]);
$payLog->addInfo(['content'=>json_encode($data)]);
// 实例化账单模型
$OrderModel = new AppleOrder();
// 账单信息
$orderInfo = $OrderModel->getInfo(['id'=>$data['attach']],'*');
if (empty($orderInfo))
$this->returnCode(50000001, '账单不存在');
if($orderInfo['pay_status'] != 1 || !empty($orderInfo['pay_time']))
$this->returnCode(50000001,'订单已支付,请勿再次支付');
// 保存微信服务器返回的签名sign
$dataSign = $data['sign'];
$return_code = $data['return_code'];
$result_code = $data['result_code'];
$data['body'] = '会员卡';
$data['spbill_create_ip'] = \request()->ip();
$data['notify_url'] = $this->notify_url;
// sign 与 s 参数 不参与签名算法
unset($data['sign']);
unset($data['transaction_id']);
unset($data['coupon_id']);
unset($data['coupon_type']);
unset($data['coupon_count']);
unset($data['coupon_fee']);
unset($data['time_end']);
unset($data['return_code']);
unset($data['result_code']);
unset($data['is_subscribe']);
unset($data['fee_type']);
unset($data['bank_type']);
unset($data['bank_type']);
// 生成签名
$sign = $this->makeSign($data);
// 判断签名是否正确 判断支付状态
if (($sign === $dataSign) && ($return_code == 'SUCCESS') && ($result_code == 'SUCCESS'))
$OrderModel->startTrans();
try
// 账单支付成功业务处理
$appleOrderInfo = $OrderModel->where(['id'=>$orderInfo['id']])->lock(true)->find();
$result = $appleOrderInfo->addInfo(['pay_status'=>2,'pay_time'=>time()],['id'=>$orderInfo['id']]);
if(!$result)
$OrderModel->rollback();
$this->returnCode(5000003, '修改订单失败,失败原因:'.$OrderModel->getError());
$appleUserModel = new AppleUser();
$appleUserInfo = $appleUserModel->where(['openid'=>$orderInfo['openid']])->lock(true)->find();
$appleUser = $appleUserInfo->where(['openid'=>$orderInfo['openid']])->setInc('moxibustion',$orderInfo['moxibustion']);
if(!$appleUser)
$OrderModel->rollback();
$this->returnCode(5000003, '添加会员针灸次数失败,失败原因:'.$appleUserModel->getError());
catch (\Exception $exception)
$OrderModel->rollback();
$this->returnCode(5000003, '操作失败,失败原因:'.$exception->getMessage());
$OrderModel->commit();
// 返回状态
die(json(['code'=>0,'支付成功']));
// 返回状态
$this->returnCode(2000003, '签名失败');
以上是关于微信小程序商城如何接入微信支付的功能?的主要内容,如果未能解决你的问题,请参考以下文章