微信小程序 - 支付(后端代码实现)
小程序支付
业务流程时序图 官方文档

步骤:
1. Openid
在小程序初次加载的时候就已经获取(详情见 小程序登录)
2. 生成商户订单
1.商品信息由小程序端提供
2.提供支付统一下单接口所需参数
3. 调用支付统一下单API
4. 拿到返回预付单信息并处理
5. 再次签名
案例:
小程序端
test.wxml
<button bind:tap="pay">支付</button>
test.js
Page({
pay:function(){
wx.request({
url: "http://127.0.0.1:8000/pay/",
method: "POST",
data:{"login_key":wx.getStorageSync("login_key")},
header: { "content-type": "application/json" },
success: function (e) {
console.log(e)
// 签权调起支付
wx.requestPayment({
'timeStamp': e.data.data.timeStamp,
'nonceStr': e.data.data.nonceStr,
'package': e.data.data.package,
'signType': e.data.data.signType,
'paySign': e.data.data.paySign,
'success': function (res)
{
console.log(res,"成功")
},
'fail': function (res)
{
console.log("支付失败",res)
},
})
}
})
},
})
后端 django
wx
├── settings.py # 小程序id,code2Session等配置
├── wx_login.py # 用于调用code2Session拿到openid等
└── WXBizDataCrypt.py # 获取用户授权信息的解密算法,官方下载
wx/settings.py
AppId="..." 微信分配的小程序id
AppSecret="..."
code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
pay_mchid ='...' 微信配的商户id
pay_apikey = '...' 商户平台设置的秘钥key
项目/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.cache import cache
import hashlib,time
import random
from app01.wx import settings
import requests
class Pay(APIView):
def post(self,request):
param=request.data
if param.get("login_key"):
#从redis中拿到小程序端login_key所对应得opendi&session_key值
openid,session_key=cache.get(param.get("login_key")).split("&")
self.openid=openid
# 获取用户IP
# 1.如果是Nginx做的负载就要HTTP_X_FORWARDED_FOR
if request.META.get('HTTP_X_FORWARDED_FOR'):
self.ip =request.META['HTTP_X_FORWARDED_FOR']
else:
# 2.如果没有用Nginx就用REMOTE_ADDR
self.ip = request.META['REMOTE_ADDR']
# 调用 生成商户订单 方法
data = self.pay()
return Response({"code":200,"msg":"ok","data":data})
else:
return Response({"code":200,"msg":"缺少参数"})
# 生成随机字符串
def get_str(self):
str_all="1234567890abcdefghjklmasdwery" # 注意 开发活动功能时, 去掉1,i,0,o
nonce_str="".join(random.sample(str_all,20))
return nonce_str
# 生成订单号
def get_order(self):
order_id=str(time.strftime("%Y%m%d%H%M%S"))
return order_id # 处理返回预付单方法
def xml_to_dict(self,data):
import xml.etree.ElementTree as ET
xml_dict={}
data_dic=ET.fromstring(data)
for item in data_dic:
xml_dict[item.tag]=item.text
return xml_dict # 获取sign签名方法
def get_sign(self):
data_dic = {
"nonce_str": self.nonce_str,
"out_trade_no": self.out_trade_no,
"spbill_create_ip": self.ip,
"notify_url": self.notify_url,
"openid": self.openid,
"body": self.body,
"trade_type": "JSAPI",
"appid": self.appid,
"total_fee": self.total_fee,
"mch_id": self.mch_id
}
sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
return md5.hexdigest().upper() # 1.生成商户订单 提供 支付统一下单 所需参数
def pay(self):
self.appid=settings.AppId # appid 微信分配的小程序ID
self.mch_id=settings.pay_mchid # mch_id 微信分配的商户号
self.nonce_str=self.get_str() # 随机字符串
self.body="商品名" # 商品名一般由小程序端传到后端
self.out_trade_no=self.get_order() # 订单号
self.total_fee=1 # 订单总金额
self.spbill_create_ip=self.ip # 用户ip
self.notify_url="http://www.baidu.com" # 异步接收微信支付结果通知的回调地址
self.trade_type="JSAPI" # 固定写法
self.sign = self.get_sign() # 获取sign 签名
data=f'''
<xml>
<appid>{self.appid}</appid>
<body>{ self.body}</body>
<mch_id>{self.mch_id}</mch_id>
<nonce_str>{self.nonce_str}</nonce_str>
<notify_url>{self.notify_url}</notify_url>
<openid>{self.openid}</openid>
<out_trade_no>{self.out_trade_no}</out_trade_no>
<spbill_create_ip>{self.spbill_create_ip}</spbill_create_ip>
<total_fee>{self.total_fee}</total_fee>
<trade_type>{self.trade_type}</trade_type>
<sign>{self.sign}</sign>
</xml>
'''
# 2.支付统一下单接口
url="https://api.mch.weixin.qq.com/pay/unifiedorder"
# 3.返回预付单信息
response=requests.post(url,data.encode("utf-8"),headers={"content-type":"application/xml"})
res_data=self.xml_to_dict(response.content)
data=self.two_sign(res_data["prepay_id"]) # prepay_id 预支付订单回话标识
return data # 4.将组合数据再次签名
def two_sign(self,prepay_id):
timeStamp=str(int(time.time()))
nonceStr=self.get_str()
data_dict={
"appId":settings.AppId,
"timeStamp":timeStamp,
"nonceStr":nonceStr,
"package":f"prepay_id={prepay_id}",
"signType":"MD5"
}
sign_str = "&".join([f"{k}={data_dict[k]}" for k in sorted(data_dict)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign=md5.hexdigest().upper()
data_dict["paySign"]=sign
data_dict.pop("appId")
# 5.返回支付参数到小程序端,小程序端获取所需参数向微信服务器发送 调起支付 方法
return data_dict
项目/urls.py
url(r'^pay/',views.Pay.as_view())
微信小程序 - 支付(后端代码实现)的更多相关文章
- 微信小程序支付之代码详解
微信小程序自带的一套规则,类似vue语法,但是好多功能都集成在api中,给了很多初学者轮子,所以首先要熟悉这些api,忘记可照官网继续开发 这里主要说下微信小程序的支付,原理类似上篇介绍的公众网页支付 ...
- Java 后端微信小程序支付demo (网上说的坑里面基本上都有)
Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...
- 微信小程序支付源码,后台服务端代码
作者:尹华南,来自原文地址 微信小程序支付绕坑指南 步骤 A:小程序向服务端发送商品详情.金额.openid B:服务端向微信统一下单 C:服务器收到返回信息二次签名发回给小程序 D:小程序发起支付 ...
- 微信小程序支付C#后端源码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 微信小程序支付及退款流程详解
微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端 ...
- .NET Core 微信小程序支付——(统一下单)
最近公司研发了几个电商小程序,还有一个核心的电商直播,只要是电商一般都会涉及到交易信息,离不开支付系统,这里我们统一实现小程序的支付流程(与服务号实现步骤一样). 目录1.开通小程序的支付能力2.商户 ...
- php 微信小程序支付
php 微信小程序支付 直接贴代码: 前端测试按钮wxml: <view class="container"> <text class="name&qu ...
- 微信小程序支付步骤
http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...
- 微信小程序 PHP后端form表单提交实例详解
微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...
随机推荐
- guppy
1.下载 wget https://mirror.oxfordnanoportal.com/software/analysis/ont-guppy-cpu_3.4.1_linux64.tar.gz
- 最小费用最大流 学习笔记&&Luogu P3381 【模板】最小费用最大流
题目描述 给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 题目链接 思路 最大流是没有问题的,关键是同时保证最小费用,因此,就可以把 ...
- linux jdk1.8 64位下载永久地址,ubuntu,centos,java
https://pan.baidu.com/s/1A4cl3vUWCtiHxJ9eHK2ApQ 密码:j8dg
- FFmpeg 是什么?
笔者才开始学习音视频开发,主要是通过阅读刘歧.赵文杰编著的<FFmpeg从入门到精通>以及雷霄骅博士博客总结写的入门心得体会. 官方文档资料 FFmpeg官方文档:https://ffmp ...
- Django学习笔记(15)——中间件
当Django处理一个Request的过程是首先通过中间件,然后再通过默认的URL方式进行的.我们可以在Middleware这个地方把所有Request拦截住,用我们自己的方式完成处理以后直接返回Re ...
- 解锁云原生 AI 技能|在 Kubernetes 上构建机器学习系统
本系列将利用阿里云容器服务,帮助您上手 Kubeflow Pipelines. 介绍 机器学习的工程复杂度,除了来自于常见的软件开发问题外,还和机器学习数据驱动的特点相关.而这就带来了其工作流程链路更 ...
- 2019-11-25-win10-uwp-发布旁加载自动更新
原文:2019-11-25-win10-uwp-发布旁加载自动更新 title author date CreateTime categories win10 uwp 发布旁加载自动更新 lindex ...
- 基于SqlClient开发SQLServer工具类 伸手党的福音
注意:代码直接Copy调用即可,SQLServer工具类跟我上一个Oracle工具类有所不同,区别在于调用存储过程中时参数的使用,无需输入对应的存储游标名称 特点:根据用户传入的参数类型来识别存储中对 ...
- WebGIS之MapBox篇
前面在Arcgis的基础上玩了玩,这不最近又去摸索了一下Web上开源的GIS;这次选择了基于MapBox来实现一些效果: 1.加载自己发布的本地瓦片效果 2.加载热力图.Echarts.三位建筑.路况 ...
- Filco圣手二代双模蓝牙机械键盘连接方法
转自:https://www.cnblogs.com/goldenSky/p/11437780.html 常规方法 确认键盘的电源接通. 同时按下「Ctrl」+「Alt」+「Fn」执行装置切换模式.配 ...