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

步骤:
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放到了 ...
随机推荐
- FT_Get_Var error on comiling
[Julian@julian-linux-t450 gtk]$ gcc `pkg-config --cflags gtk+-.` -o exam00 exam00.c `pkg-config --li ...
- Excel日历控件实现下拉选取日期含VB代码实现
以下是Excel2016通过安装控件,实现表格下拉选择日期的一些步骤: 知识准备工作:先了解下如何安装控件,这一部分很重要,excel选择可用宏https://jingyan.baidu.com/ar ...
- mysql不是内部或外部命令--windows环境下报错的解决
安装Mysql后,当我们在cmd中敲入mysql时会出现‘Mysql’不是内部或外部命令,也不是可运行的程序或其处理文件. 处理: 我的电脑右键属性>高级系统设置>高级>环境变量&g ...
- RocketMQ的顺序消费和事务消费
一.三种消费 :1.普通消费 2. 顺序消费 3.事务消费 1.1 顺序消费:在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成.也就是这个三个 ...
- 小米笔记本pro 黑苹果系统无法进入系统,频繁重启故障解决记录
问题1:频繁重启,然后clover丢失 表现情况:开机没有选择macos 或windos的界面 解决办法:进入windows使用工具easyefi,直接添加一个clover start boot,选择 ...
- LeetCode 206:反转链表 Reverse Linked List
反转一个单链表. Reverse a singly linked list. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3- ...
- linux内核参数sysctl.conf,TCP握手ack,洪水攻击syn,超时关闭wait
题记:优化Linux内核sysctl.conf参数来提高服务器并发处理能力 PS:在服务器硬件资源额定有限的情况下,最大的压榨服务器的性能,提高服务器的并发处理能力,是很多运维技术人员思考的问题.要提 ...
- WPF Adorner 简易图片取色器
回答MSDN问题所写. 使用Adorner+附加属性 图片类(来自这位博主的博客) /// <summary> /// 用于获取位图像素的类 /// </summary> pu ...
- MySQL for OPS 08:MHA 高可用
写在前面的话 主从架构在一般情况下只能满足我们小公司业务并非一刻都不能中断服务.但是对于大型公司而言,对然数据丢失,数据库挂了,我们可以通过技术找回,修复.但是其中修复过程所消耗的时间是不被允许的.此 ...
- dubbo入门学习
官方网址:http://dubbo.apache.org/zh-cn/index.html 学习可以参考官网中文文档:http://dubbo.apache.org/zh-cn/docs/user/q ...