微信 JSAPI 支付

编程入门 行业动态 更新时间:2024-10-22 03:03:40

微信 <a href=https://www.elefans.com/category/jswz/34/1759924.html style=JSAPI 支付"/>

微信 JSAPI 支付

一、申请微信公众号、开通微信支付,通过【APPID】将两者关联,具体操作步骤参考:点击查看

二、在公众号管理后台设置【接收微信支付异步回调通知域名】,

三、在微信支付管理后台设置【支付授权域名】及【KEY】,支付授权域名与接收回调通知域名最好为同域名,

四、生成支付需要的配置文件

五、首次访问网站时静默获取用户 OPENID

六、用户点击支付时,调用微信【统一下单接口】,获取 PREPAY_ID

七、生成 JSAPI 支付需要的参数

八、用户输完支付密码,前台轮询订单状态,后台在 NOTIFY_URL 中处理订单

九、PHP demo如下:

<?phpreturn $config = array('SITE_URL' => '/','WEIXINPAY_CONFIG' => array('APPID'      => 'wxf96fa703d64967cc', // 公众号后台获取'APPSECRET'  => 'e2e87179cfe614dfa0ca16146b0cdfe3', // 公众号后台获取,用于获取用户OPENID'MCHID'      => '1582427110', // 微信支付后台获取,'PAY_KEY'    => 'a5f5764bc7905be3075c79d1ce216014', // 微信支付后台设置,用于参数签名'NOTIFY_URL' => '/', // 异步接收微信支付结果地址,不能有任何鉴权逻辑,能在浏览器中访问'TRADE_TYPE' => 'JSAPI', // 支付类型),
);?><?phpclass HomeController extends Controller
{public function __construct(){parent::__construct();}/*** 首页**/public function panel(){# code here...
    }/*** 引导页**/public function index(){// 微信静默授权if (empty($_SESSION['wx_openid'])) {$appid = $config['WEIXINPAY_CONFIG']['APPID'];$jump_url = $config['SITE_URL'] . 'home/index/wxoauth2/';$oauth2_url  = '=' . $appid;$oauth2_url .= '&redirect_uri=' . urlencode($jump_url);$oauth2_url .= '&response_type=code';$oauth2_url .= '&scope=snsapi_base';$oauth2_url .= '&state=STATE#wechat_redirect';redirect($oauth2_url);} else {redirect('/home/panel/');}}/*** 不弹出询问获取用户OPENID**/public function wxoauth2(){$url  = '=' . $config['WEIXINPAY_CONFIG']['APPID'];$url .= '&secret=' . $config['WEIXINPAY_CONFIG']['APPSECRET'];$url .= '&code=' . trim($_GET['code']);$url .= '&grant_type=authorization_code';$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$output = curl_exec($ch);if (curl_error($ch)) {redirect('/home/index');}curl_close($ch);$result = json_decode($output, true);if (!empty($result['openid'])) {$_SESSION('wx_openid', $result['openid']);redirect('/home/panel/');}redirect('/home/index');}/*** 用户发请AJAX支付请求** 请自先定义 api_error(), api_success(), array2xml(), xml2array(), write_log()**/public function wxpay(){is_weixin() or exit(api_error('请在微信中打开...'));if (empty($_SESSION['user_id'])) {redirect($config['SITE_URL']);}if (empty($_POST['total_fee'])) {exit(api_error('支付金额为0'));}if (empty($_POST['goods_id'])) {exit(api_error('待支付商品不存在'));}$nonce_str = md5(uniqid(null, true) . mt_rand());$out_trade_no = crc32($nonce_str);// 调用统一下单接口获取prepay_id$unifiedorder_params = array('appid'             => $config['WEIXINPAY_CONFIG']['APPID'],'mch_id'            => $config['WEIXINPAY_CONFIG']['MCHID'],'trade_type'        => $config['WEIXINPAY_CONFIG']['TRADE_TYPE'],'notify_url'        => $config['WEIXINPAY_CONFIG']['NOTIFY_URL'],'openid'            => $_SESSION['wx_openid'],'nonce_str'         => $nonce_str,'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],'out_trade_no'      => $out_trade_no,'body'              => '微信支付后台商家名称-商品类目名' . rand(1, 100),'total_fee'         => $_POST['total_fee'] * 100,'product_id'        => $_POST['goods_id'],);ksort($unifiedorder_params);$tmp_str  = http_build_query($unifiedorder_params);$tmp_str .= '&key=' . $config['WEIXINPAY_CONFIG']['PAY_KEY'];$sign = md5($tmp_str);$unifiedorder_params['sign'] = strtoupper($sign);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, '');curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/xml'));curl_setopt($ch, CURLOPT_POSTFIELDS, array2xml($unifiedorder_params));$output = curl_exec($ch);if ($errmsg = curl_error($ch)) {exit(api_error($errmsg));}curl_close($ch);$unifiedorder = xml2array($output);if (empty($unifiedorder['prepay_id'])) {exit(api_error('微信预支付订单生成失败'));}write_log($unifiedorder);// 生成JSAPI参数$jsapi_params = array('appId'     => $config['WEIXINPAY_CONFIG']['APPID'],'timeStamp' => time(),'nonceStr'  => $nonce_str,'package'   => 'prepay_id=' . $unifiedorder['prepay_id'],'signType'  => 'MD5',);ksort($jsapi_params);$tmp_str  = http_build_query($jsapi_params);$tmp_str .= '&key=' . $config['WEIXINPAY_CONFIG']['PAY_KEY'];$sign = md5($tmp_str);$jsapi_params['paySign'] = strtoupper($sign);$jsapi_params['order_no'] = $out_trade_no; // 用于前台轮询订单状态write_log($jsapi_params);// 商户订单入库$order = array('pay_state'   => 0, // 0待支付 1支付成功 2支付失败'pay_price'   => $_POST['total_fee'],'pay_type'    => $config['WEIXINPAY_CONFIG']['TRADE_TYPE'],'pay_order'   => $out_trade_no,'user_id'     => $_SESSION['user_id'],'goods_id'    => $_POST['goods_id'],'create_time' => time(),);if (!(M('t_order')->add($order))) {$order['errmsg'] = '商户订单入库失败';write_log($order);exit(api_error('支付失败,请重新发起支付请求'));}exit(api_success($jsapi_params));}/*** 微信支付异步通知**/public function wxpay_sync_notice(){write_log('微信异步通知--start--');// 获取微信通知$xml = file_get_contents('php://input', 'r');$notify = xml2array($xml);if (!isset($notify['return_code'], $notify['result_code'])|| $notify['return_code'] !== 'SUCCESS'|| $notify['result_code'] !== 'SUCCESS') {$log = array('errmsg' => '微信未返回return_code、result_code为SUCCESS','wx_sync_notice' => $notify, );write_log($log);$pay_fail = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';exit($pay_fail);}if (empty($notify['sign']) || $notify['out_trade_no']) {$log = array('errmsg' => '微信未返回签名或订单号','wx_sync_notice' => $notify, );write_log($log);$pay_fail = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';exit($pay_fail);}// 验证签名$wx_sign = $notify['sign'];unset($notify['sign']);ksort($notify);$tmp_str  = http_build_query($notify);$tmp_str .= '&key=' . $config['WEIXINPAY_CONFIG']['PAY_KEY'];$valid_sign = strtoupper(md5($tmp_str));if ($wx_sign !== $valid_sign) {$log = array('errmsg' => '微信返回的签名未通过验证','wx_sync_notice' => $notify,'valid_sign' => $valid_sign,);write_log($log);$pay_fail = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';exit($pay_fail);}// 验证订单金额及状态$where = "order_no = " . $notify['out_trade_no'];$order = M('t_order')->where($where)->find();if (empty($order) || $order['pay_price'] != $notify['total_fee'] / 100) {$log = array('errmsg' => '商户订单不存在或微信返回的订单金额与商户订单金额不一致','wx_sync_notice' => $notify,'order_info' => $order,);write_log($log);$pay_fail = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';exit($pay_fail);}if ($order['pay_state'] == 1) {$log = array('errmsg' => '订单已被标记为‘支付成功’(重复异步通知)','wx_sync_notice' => $notify,'order_info' => $order,);write_log($log);$pay_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';exit($pay_success);}// 更新订单$data = array('pay_state' => 1,'pay_time' => time(),);$update = M('t_order')->where($where)->save($data);if ($update === false) {$log = array('errmsg' => '商户更新订单状态为‘成功’时失败','wx_sync_notice' => $notify,'order_info' => $order,'update_order' => $data,);write_log($log);$pay_fail = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';exit($pay_fail);}// 销量+1 库存-1// code here...
write_log("支付成功.\n微信异步通知--end--\n\n");$pay_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';exit($pay_success);}/*** 检查订单支付状态**/public function order_state(){$order_no = $_POST['order_no'];if (empty($order_no)) {exit('FAIL');}$map['pay_order'] = $order_no;$map['pay_state'] = 1;$order = M('t_order')->where($map)->find();if (empty($order)) {exit('FAIL');}exit('SUCCESS');}// end all
}?>

 

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>微信支付</title><style type="text/css">input#pay_btn.disabled {pointer-events: none;background: #ccc;}input#pay_btn:link,input#pay_btn:visited,input#pay_btn:hover,input#pay_btn:active {outline: none;box-shadow: none;}</style>
</head>
<body><form id="pay_form"><input type="text" name="total_fee" value="5.9"><input type="hidden" name="goods_id" value="100256"><input type="button" name="" value="点击支付" id="pay_btn" class=""></form>
</body><script src="//layer-v3.0.3/layer/layer.js"></script>
<script type="text/javascript">function check_order_state(order_no){intvl = setInterval(function () {$.ajax({url: '<?= $config['SITE_URL'] . 'home/order_state/' ?>',type: 'POST',data: {order_no: order_no}}).done(function (msg) {if (msg === 'SUCCESS') {clearInterval(intvl);alert('支付成功');} else {console.log('pay fail...');}});}, 1000);}function onBridgeReady(data){WeixinJSBridge.invoke('getBrandWCPayRequest', data, function (res) {layer.closeAll();if (res.err_msg == "get_brand_wcpay_request:ok") {// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                check_order_state(data.order_no);} else if (res.err_msg == "get_brand_wcpay_request:cancel") {alert('已取消支付');} else {alert('支付失败');}return false;}); }$('#pay_btn').click(function () {$.ajax({url: '<?= $config['SITE_URL'] . 'home/wxpay/' ?>',type: 'post',data: $('#pay_form').serialize(),dataType: 'json',beforeSend: function () {$('#pay_btn').addClass('disabled');layer.msg('支付中,请稍候...', {icon: 16, shade: 0.3});},}).done(function (data) {setTimeout(function () {layer.closeAll();$('#pay_btn').removeClass('disabled');if (data.errmsg) {layer.msg(data.errmsg);return false;}// 调起微信支付
                onBridgeReady(data.data);}, 2000);}).fail(function () {layer.closeAll();$('#pay_btn').removeClass('disabled');layer.msg('支付失败,请重新点击支付!');});});
</script></html>

 

更多推荐

微信 JSAPI 支付

本文发布于:2024-03-08 05:46:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1719971.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:JSAPI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!