微信小程序支付

1.微信支付的流程大致分为四步骤:

1.在小程序中获取用户的登录信息,成功后可以获取到用户的code值

2.在用户自己的服务端请求微信获取用户openid接口,成功后可以获取用户的openid值

微信官方api地址:点击打开链接

3.在用户自己的服务器上面请求微信的统一下单接口,下单成功后可以获取prepay_id值

微信官方api地址:点击打开链接

4.在微信小程序中支付订单,最终实现微信的支付功能

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3

具体的流程图如下所示:

2.关键代码

2.1 获取用户的信息,也就是小程序中的登录接口:

小程序代码部分


    onGetOpenId(){
            var that = this 
            var wxcode = ''
             //调用微信API获取wxcode
            wx.login({
                success:function(res)
                {
                    console.log('loginCode:', res.code)
                    wxcode = res.code  
                    //调用后端API获取appid
                      that.$http.get('/getappid/'+wxcode)
                    .then(function(res){
                      console.log(res)
                      var openid = res.data.openid
                      var session_key = res.data.session_key


                    })
                    .catch(function(error){
                        console.log('获取openid失败1')

                        return fail
                    })
                } 
            });
        },

后端代码部分(使用PYTHON)

APPID = 'XXX'
SECRET = 'XXX'
class WxApi(Resource):
    def get(self, wxcode):
        print('wxcode=', wxcode)
        r = requests.get(
            'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret=XXXX&js_code={}&grant_type=authorization_code'
            .format(APPID,SECRET,wxcode))

        print('openid={}  session_key={}'.format(r.json()['openid'],
                                                 r.json()['session_key']))
        return {
            'message': 'success',
            'session_key': r.json()['session_key'],
            'openid': r.json()['openid']
        }


api.add_resource(WxApi, '/api/getappid/<wxcode>')

2.2 调用微信接口获取prepayid

前端代码部分

onSubmitClick:function(){
    //访问后端服务部分
    that.$http.post('/prepayid',{
                'openid':that.GLOBAL.openid,
                'spbill_create_ip':myip,
                'total_fee':that.g_tprice,
            })
            .then(function(res){
                console.log('获取prepayid返回')
                console.log(res)
                console.log(res.data.data.package)
                //调用微信支付接口
                wx.requestPayment(
                {
                'timeStamp': res.data.data.timeStamp,
                'nonceStr':res.data.data.nonceStr,
                'package': res.data.data.package,
                'signType': res.data.data.signType,
                'paySign': res.data.data.paySign,
                'success':function(res){
                    console.log(res)
                },
                'fail':function(res){},
                'complete':function(res){}
                })

            })
            .catch(function(res){
                console.log('获取prepayid error返回')
                console.log(res)
            })
        }

后端代码部分

import datetime, os, re
import requests
import hashlib
from time import strftime, strptime, mktime, time
import random
import xmltodict
import string

APPID = 'xxxx'
MCHID = 'xxxxx'
KEY = 'xxxxxx'
NOTIFY_URL = 'xxxxx'


# 生成32位随机数
def generate_nonce_str():
    ran_str = ''.join(random.sample(string.ascii_letters + string.digits, 32))
    return ran_str


# 生成签名
def generate_sign(param):
    stringA = ''
    print('param={}'.format(param))
    ks = sorted(param.keys())
    print('ks={}'.format(ks))
    # 参数排序
    for k in ks:
        print('k={} param[k]={}'.format(k, param[k]))
        stringA += (k + '=' + str(param[k]) + '&')
        print(stringA)
    # 拼接商户KEY
    stringSignTemp = stringA + "key=" + KEY
    print('stringSignTemp={}'.format(stringSignTemp))
    # md5加密
    hash_md5 = hashlib.md5(stringSignTemp.encode('utf8'))
    sign = hash_md5.hexdigest().upper()
    return sign




def trans_dict_to_xml(data):
    """
    将 dict 对象转换成微信支付交互所需的 XML 格式数据
    :param data: dict 对象
    :return: xml 格式数据
    """

    xml = []
    for k in data.keys():
        v = data.get(k)
        v = '<![CDATA[{}]]>'.format(v)
        xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
    return '<xml>{}</xml>'.format(''.join(xml))


# 发送xml请求
def send_xml_request(url, param):
    # dict 2 xml
    # param = {'root': param}
    xml = trans_dict_to_xml(param)
    print('xml = {}'.format(xml))
    response = requests.post(
        url, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
    print('send success')
    # xml 2 dict
    msg = response.text
    xmlmsg = xmltodict.parse(msg)
    print('xmlmsg={}'.format(xmlmsg))

    return xmlmsg


# 调用微信小程序统一下单api
def generate_bill(out_trade_no, fee, openid):
    url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
    rnonce_str = generate_nonce_str()
    # 1. 参数
    param = {
        "appid": APPID,
        "mch_id": MCHID,  # 商户号
        "nonce_str": rnonce_str,  # 随机字符串
        "body": 'TEST_pay',  # 支付说明
        "out_trade_no": out_trade_no,  # 自己生成的订单号
        "total_fee": fee,
        "spbill_create_ip": '127.0.0.1',  # 发起统一下单的ip
        "notify_url": NOTIFY_URL,
        "trade_type": 'JSAPI',  # 小程序写JSAPI
        "openid": openid,
    }
    # 2. 获取数字签名
    sign = generate_sign(param)
    param["sign"] = sign  # 加入签名
    print('param sigin={}'.format(param))
    # 3. 调用接口
    xmlmsg = send_xml_request(url, param)
    # 4. 获取prepay_id
    if xmlmsg['xml']['return_code'] == 'SUCCESS':
        if xmlmsg['xml']['result_code'] == 'SUCCESS':
            prepay_id = xmlmsg['xml']['prepay_id']
            # 时间戳
            timeStamp = str(int(time()))
            # 5. 五个参数
            data = {
                "appId": APPID,
                "nonceStr": rnonce_str,
                "package": "prepay_id=" + prepay_id,
                "signType": 'MD5',
                "timeStamp": timeStamp,
            }
            print('data = {}'.format(data))
            # 6. paySign签名
            paySign = generate_sign(data)
            data["paySign"] = paySign  # 加入签名
            # 7. 传给前端的签名后的参数
            return data

class WxPrepay_idApi(Resource):
    """
    获取微信小程序支付
    """

    def post(self):
        args = parse.parse_args()
        openid = args['openid']
        total_fee = args['total_fee']
        spbill_create_ip = args['spbill_create_ip']
        out_trade_no = generate_id('wxapp')
        print('openid={} total_fee={}'.format(openid, total_fee))
        data = generate_bill(openid=openid, out_trade_no=out_trade_no, fee=10)

        return {'message': 'success', 'data': data}


api.add_resource(WxPrepay_idApi, '/api/prepayid')

results matching ""

    No results matching ""