微信后台环境配置:
一、设置支付目录
支付授权目录说明:
1、商户最后请求拉起微信支付收银台的页面地址我们称之为“支付目录”,例如:https://www.weixin.com/pay.php。
2、商户实际的支付目录必须和在微信支付商户平台设置的一致,否则会报错“当前页面的URL未注册:”支付授权目录设置说明:
登录微信支付商户平台(http://pay.weixin.qq.com)-->产品中心-->开发配置,设置后一般5分钟内生效。支付授权目录校验规则说明:
1、如果支付授权目录设置为顶级域名(例如:https://www.weixin.com/ ),那么只校验顶级域名,不校验后缀;
2、如果支付授权目录设置为多级目录,就会进行全匹配,例如设置支付授权目录为https://www.weixin.com/abc/123/,则实际请求页面目录不能为https://www.weixin.com/abc/,也不能为https://www.weixin.com/abc/123/pay/,必须为https://www.weixin.com/abc/123/
特别注意的是 目录 目录 目录 比如我的配置为 域名 /app/api/user 不可以是 /app/api/user/buy_vip
二、设置授权域名
开发JSAPI支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。具体界面如图7.8所示:
程序文件:
PaymentController.php
<?php
//+-----------------------------------------------------------------------------
//| Thinkcmf [ WE CAN DO IT MORE SIMPLE ]
//+-----------------------------------------------------------------------------
//| Copyright (c) 2019-2019 http://my.uckoo.net All rights reserved.
//+-----------------------------------------------------------------------------
//| Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
//+-----------------------------------------------------------------------------
//| CreateTime 2020-03-12
//+-----------------------------------------------------------------------------
//| Author: JQ
//+-----------------------------------------------------------------------------
namespace appapicontroller;
use OvertrueWechatAuth;
use OvertrueWechatPayment;
use OvertrueWechatPaymentBusiness;
use OvertrueWechatPaymentNotify;
use OvertrueWechatPaymentOrder;
use OvertrueWechatPaymentUnifiedOrder;
use thinkController;
use thinkDb;
class PaymentController extends Controller
{
/**
* 生成訂單
* @param string openid 用戶唯一標識
* @param int buy_type 購買類型 默認1 購買會員 2 購買積分
*/
public function payment($openid,$buy_type=1)
{
$total_free = '1';
$notify_url = $buy_type == 1 ? '回调地址你的域名/payment/notify' : '回调地址你的域名/payment/score_notify';
// $openid = input('openid');
/**
* 第 1 步:定义商户
*/
$Business = new Business(APP_ID, APP_KEY, MCH_ID, MCH_KEY);
/**
* 第 2 步:定义订单
*/
$order = new Order();
$order->body = '充值中心-會員充值';
$order->out_trade_no = md5(uniqid() . microtime());
$order->total_fee = $total_free; // 单位为 “分”, 字符串类型
$order->openid = $openid;
$order->notify_url = $notify_url;
// $order->trade_type = "MWEB";//H5支付的交易类型为MWEB
// $order->scene_info ='{"h5_info": {"type":"Wap","wap_url": "http://limited.sz3.hostadm.net","wap_name": "Kongec互惠平台-會員充值"}}';
/**
* 第 3 步:统一下单
*/
// var_dump($order);die;
$unifiedOrder = new UnifiedOrder($Business, $order);
/**
* 第 4 步:生成支付配置文件
*/
$payment = new Payment($unifiedOrder);
$payment_config = $payment->getConfig();
return $payment_config;
}
/**购买会员回调 */
public function notify()
{
$notify = new Notify(
APP_ID,
APP_KEY,
MCH_ID,
MCH_KEY
);
$transaction = $notify->verify();
error_log($transaction, 3, 'pay_log.txt');
if (!$transaction) {
$notify->reply('FAIL', 'verify transaction error');
}
//处理用户值支付成功后的操作
$user = Db::name('user')->where(['openid' => $transaction->openid])->find();
$pay_log = Db::name('pay_log')->where(['user_id' => $user['id']])->order('id desc')->value('log');
$pay_log = json_decode($pay_log, true);
//避免订单重复数据表操作
if ($pay_log['out_trade_no'] !== $transaction->out_trade_no) {
......
Db::startTrans();
try {
......
Db::name('pay_log')->insert([
'user_id' => $user['id'],
'amount' => ($transaction->total_fee) / 100,
'create_time' => time(),
'description' => "",
'log' => $transaction,
'status' => 1,
'pay_type' => 1,
'pay_way' => 1
]);
// 提交事务
Db::commit();
} catch (Exception $e) {
// 回滚事务
Db::rollback();
}
//回复微信已经收到返回信息 特别重要 不然微信会持续发送返回信息
return $notify->reply($transaction->return_code, "SUCCESS");
}
}
//获取用户微信信息 JSAPI 方式支付需要用的openid H5 则不需要
public function get_openid()
{
$auth = new Auth(APP_ID, APP_KEY);
session_start();
if (empty($_SESSION['logged_user'])) {
$user = $auth->authorize(); // 返回用户 Bag
$_SESSION['logged_user'] = $user->all();
// 跳转到其它授权才能访问的页面
} else {
$user = $_SESSION['logged_user'];
}
return $user;
}
}
UserController.php
<?php
//+-----------------------------------------------------------------------------
//| Thinkcmf [ WE CAN DO IT MORE SIMPLE ]
//+-----------------------------------------------------------------------------
//| Copyright (c) 2019-2019 http://my.uckoo.net All rights reserved.
//+-----------------------------------------------------------------------------
//| Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
//+-----------------------------------------------------------------------------
//| CreateTime 2020-02-10
//+-----------------------------------------------------------------------------
//| Author: JQ
//+-----------------------------------------------------------------------------
namespace appapicontroller;
use appadmin_extendmodelNewsModel;
use cmfcontrollerHomeBaseController;
use OvertrueWechatJs;
use thinkCookie;
use thinkDb;
use thinkSession;
class UserController extends HomeBaseController
{
/**
* 開通會員
*/
public function buy_vip()
{
//调起支付接口
$PaymentController =new PaymentController();
$user_openid = Db::name('user')->where(['id'=>$this->user['id']])->value('openid');
if(empty($user_openid)){
$WeixinUserInfo = $PaymentController->get_openid();
if(!empty($WeixinUserInfo['openid'])){
$user_openid = Db::name('user')->where(['id'=>$this->user['id']])->setField('openid',$WeixinUserInfo['openid']);
}
$user_openid = $WeixinUserInfo['openid'];
}
$WeixinConfig = $PaymentController->payment($user_openid );
$this->assign('WeixinConfig', $WeixinConfig);
return $this->fetch('portal@user/buy_vip');
}
}
前端 buy_vip.html
<!DOCTYPE html>
<html lang="en">
<head>
<include file="portal@public/head" />
</head>
<body>
<div class="head_box">
<div class="public_head">
<div class="head_back"></div>
<div class="head_title">開通會員</div>
</div>
<div class="head_place"></div>
</div>
<div class="user_page" style="padding-bottom: 20px;">
<div class="user_head" style="padding-bottom: 20px;">
<include file="portal@user/bg_color" />
<div class="list_card">
<div class="login_page" style="padding-bottom:0;">
<h3 class="vip_title">會員</h3>
<div class="vip_content">
</div>
<h3 class="vip_title">會員費用</h3>
<div class="pay_price"> {$pay_money}</div>
<div class="choice_pay">選擇支付方式</div>
<div class="pay_mode_box">
<div class="pay_type1 active" data-id="1">
<span class="pay_wx"></span>
<span class="pay_rmb"></span>
</div>
</div>
<div class="yhsz_box">
<span class="yhsz_radio active"></span>
<input type="hidden" name="user_rule" value="0">
<input type="hidden" name="pay_way" value="1">
<a href="">我同意《用戶守則》</a>
</div>
</div>
</div>
</div>
<div class="pay_btn_box">
<div class="qx_pay">取消</div>
<div class="qd_pay" onclick="payMoney()">確定開通</div>
</div>
</div>
<!-- 支付成功提示 -->
<div class="pay_mask">
<div class="flex-column">
<div class="pay_success_box">
<h3>支付成功</h3>
<p class="message"></p>
</div>
<div class="close_tips"></div>
</div>
</div>
<div class="loading"></div>
<!-- 引入微信支付js -->
<script src="__TMPL__/public/assets/js/payment.js"></script>
<script>
function payMoney() {
var pay_way = $('input[name="pay_way"]').val();
if (pay_way) {
if (pay_way == 1) {
payment()
} else {
$.ajax({
url: "{:cmf_url('api/user/buy_vip_do')}",
dataType: 'json',
data: {
pay_way: pay_way
},
beforeSend: function () {
$(".loading").html(
"<img src='__TMPL__/public/assets/images/loading.gif' />"
); //在请求后台数据之前显示loading图标
},
success: function (res) {
$(".loading").empty(); //ajax返回成功,清除loading图标
if (res.code == 1) {
paySuccess(res.data.message)
} else {
layer.msg(res.msg)
}
}
})
}
}
}
/**
* 支付
*/
function payment() {
if (typeof WeixinJSBridge === 'undefined') {
alert('请在微信在打开页面!');
return false;
} else {
WeixinJSBridge.invoke('getBrandWCPayRequest', {$WeixinConfig} ,function (res) {
switch (res.err_msg) {
case 'get_brand_wcpay_request:cancel':
layer.msg('用户取消支付!');
break;
case 'get_brand_wcpay_request:fail':
layer.msg('支付失败!(' + res.err_desc + ')');
break;
case 'get_brand_wcpay_request:ok':
layer.msg('支付成功!',function(){
window.location.href = "{:cmf_url('api/user/set_info')}"
});
break;
default:
alert(JSON.stringify(res));
break;
}}
);
}
}
</script>
</body>
</html>
以上就是微信JSAPI 的支付方法 谨以此文记录学习过程 。若果有幸帮到他人,无比高兴。O(∩_∩)O哈哈~