微信小程序调用支付接口支付
今天记录一下学习的小程序调用微信支付接口
一、先理清一下调起微信支付的整个流程。
1、就是先调用微信的支付统一下单api获取到prepay_id
2、然后后端再将这个prepay_id组装好数据,发送个小程序
3、小程序根据这个数据包调起微信支付
wx.requestPayment(
{
‘timeStamp’: ‘’,
‘nonceStr’: ‘’,
‘package’: ‘’,
‘signType’: ‘MD5’,
‘paySign’: ‘’,
‘success’:function(res){},
‘fail’:function(res){},
‘complete’:function(res){}
})
二、后端的tp5操作
public function pay()
{
$this->checkOrderValid();
$order = new Order();
$status = $order->checkOrderStock($this->orderID);
if (!$status['pass'])
{
return $status;
}
return $this->makeWxPreOrder($status['orderPrice']);
// $this->checkProductStock();
}
// 构建微信支付订单信息
private function makeWxPreOrder($totalPrice)
{
$openid = Token::getCurrentTokenVar('openid');
if (!$openid)
{
throw new TokenException();
}
$wxOrderData = new \WxPayUnifiedOrder();
$wxOrderData->SetOut_trade_no($this->orderNo); //商户订单号,后续看看怎么生成的!
$wxOrderData->SetTrade_type('JSAPI'); //交易类型
$wxOrderData->SetTotal_fee($totalPrice * 100); //订单金额
$wxOrderData->SetBody('零食商贩'); //商品描述
$wxOrderData->SetOpenid($openid); //用户id
$wxOrderData->SetNotify_url(config('secure.pay_back_url')); //微信回调通知地址
return $this->getPaySignature($wxOrderData);
}
//向微信请求订单号并生成签名
private function getPaySignature($wxOrderData)
{
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
// 失败时不会返回result_code
if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
Log::record($wxOrder,'error');
Log::record('获取预支付订单失败','error');
// throw new Exception('获取预支付订单失败');
}
$this->recordPreOrder($wxOrder);
$signature = $this->sign($wxOrder);
return $signature;
}
private function recordPreOrder($wxOrder){
// 必须是update,每次用户取消支付后再次对同一订单支付,prepay_id是不同的
OrderModel::where('id', '=', $this->orderID)
->update(['prepay_id' => $wxOrder['prepay_id']]);
}
// 签名
private function sign($wxOrder)
{
$jsApiPayData = new \WxPayJsApiPay();
$jsApiPayData->SetAppid(config('wx.app_id'));
$jsApiPayData->SetTimeStamp((string)time());
$rand = md5(time() . mt_rand(0, 1000));
$jsApiPayData->SetNonceStr($rand);
$jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
$jsApiPayData->SetSignType('md5');
$sign = $jsApiPayData->MakeSign();
$rawValues = $jsApiPayData->GetValues();
$rawValues['paySign'] = $sign;
unset($rawValues['appId']);
return $rawValues;
}
/**
* @return bool
* @throws OrderException
* @throws TokenException
*/
private function checkOrderValid()
{
$order = OrderModel::where('id', '=', $this->orderID)
->find();
if (!$order)
{
throw new OrderException();
}
// $currentUid = Token::getCurrentUid();
if(!Token::isValidOperate($order->user_id))
{
throw new TokenException(
[
'msg' => '订单与用户不匹配',
'errorCode' => 10003
]);
}
if($order->status != 1){
throw new OrderException([
'msg' => '订单已支付过啦',
'errorCode' => 80003,
'code' => 400
]);
}
$this->orderNo = $order->order_no;
return true;
}
然后后台完成上面的操作后,就将数据包(存放了prepay_id的包)发送到了小程序。
三、小程序就调起支付
四、支付成功与失败就会先在小程序里回调。 然后微信服务器会异步通知我们的一开始填写的路劲:notify_url 参数,然后我们后台就修改订单状态。