小程序支付

业务流程时序图 官方文档

步骤:

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())

微信小程序 - 支付(后端代码实现)的更多相关文章

  1. 微信小程序支付之代码详解

    微信小程序自带的一套规则,类似vue语法,但是好多功能都集成在api中,给了很多初学者轮子,所以首先要熟悉这些api,忘记可照官网继续开发 这里主要说下微信小程序的支付,原理类似上篇介绍的公众网页支付 ...

  2. Java 后端微信小程序支付demo (网上说的坑里面基本上都有)

    Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...

  3. 微信小程序支付源码,后台服务端代码

    作者:尹华南,来自原文地址 微信小程序支付绕坑指南 步骤 A:小程序向服务端发送商品详情.金额.openid B:服务端向微信统一下单 C:服务器收到返回信息二次签名发回给小程序 D:小程序发起支付 ...

  4. 微信小程序支付C#后端源码

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  5. 微信小程序支付及退款流程详解

    微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端 ...

  6. .NET Core 微信小程序支付——(统一下单)

    最近公司研发了几个电商小程序,还有一个核心的电商直播,只要是电商一般都会涉及到交易信息,离不开支付系统,这里我们统一实现小程序的支付流程(与服务号实现步骤一样). 目录1.开通小程序的支付能力2.商户 ...

  7. php 微信小程序支付

    php 微信小程序支付 直接贴代码: 前端测试按钮wxml: <view class="container"> <text class="name&qu ...

  8. 微信小程序支付步骤

    http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...

  9. 微信小程序 PHP后端form表单提交实例详解

    微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...

随机推荐

  1. git相关2

    初学备忘: git安装好后,目录右键 => Git Bash here _________________________ 初始化仓库 git init 仓库名 配置仓库 git config ...

  2. 第05组团队Github现场编程实战

    第05组团队Github现场编程实战 一.组员职责分工 组员 分工 卢欢(组长) 前后端接口设计 严喜 寻找相关资料 张火标 设计并描述界面原型 钟璐英 编写随笔 周华 填写完善文档 古力亚尔·艾山 ...

  3. 线上问题排查利器Arthas

    官方文档 下载arthas-boot.jar,然后用java -jar的方式启动: curl -O https://alibaba.github.io/arthas/arthas-boot.jar j ...

  4. CSS使用知识点

    1.空白符   2.字符间距   3.省略号样式   4.水平垂直居中用法   5.CSS角标实现   空格符 1.  相当于键盘按下的空格,区别是 是可以累加的空格,键盘敲下的空格不会累加 2.  ...

  5. 微信小程序开发-蓝牙功能开发

    0. 前言 这两天刚好了解了一下微信小程序的蓝牙功能.主要用于配网功能.发现微信的小程序蓝牙API已经封装的很好了.编程起来很方便.什么蓝牙知识都不懂的情况下,不到两天就晚上数据的收发了,剩下的就是数 ...

  6. python每日学习2018/1/14(python之禅)

    The Zen of Python, by Tim Peters   Beautiful is better than ugly. Explicit is better than implicit. ...

  7. HTML+css基础 css选择器的种类

    css选择器的种类 标签   权重是001 类  class权重是0010 相当于255个标签选择器 Id   权重是0100相当于255个类 *通配符   代表所有的标签   权重是0000 后代选 ...

  8. 在.net中读写config文件的各种方法【转】

    今天谈谈在.net中读写config文件的各种方法. 在这篇博客中,我将介绍各种配置文件的读写操作. 由于内容较为直观,因此没有过多的空道理,只有实实在在的演示代码, 目的只为了再现实战开发中的各种场 ...

  9. Window权限维持(六):BITS Jobs

    Windows操作系统包含各种实用程序,系统管理员可以使用它们来执行各种任务.这些实用程序之一是后台智能传输服务(BITS),它可以促进文件到Web服务器(HTTP)和共享文件夹(SMB)的传输能力. ...

  10. Kafka学习笔记之Kafka性能测试方法及Benchmark报告

    0x00 概述 本文主要介绍了如何利用Kafka自带的性能测试脚本及Kafka Manager测试Kafka的性能,以及如何使用Kafka Manager监控Kafka的工作状态,最后给出了Kafka ...