微信支付之JSAPI支付

2024-05-28 01:32
文章标签 微信 支付 jsapi

本文主要是介绍微信支付之JSAPI支付,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JSAPI支付

JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付

使用场景

  • 用户在微信公众账号(必须是服务号)内进入商家公众号,打开某个H5页面,完成支付

  • 用户的好友在朋友圈、聊天窗口等分享商家H5页面连接,用户点击链接打开商家H5页面,完成支付

  • 将商户H5页面转换成二维码,用户扫描二维码后在微信浏览器中打开h5页面后完成支付

JSAPI接口

  • 使用JS脚本:getBrandWCPayRequest 调起微信支付

WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId": "{{.AppId}}",   //公众号名称,由商户传入"timeStamp": "{{.TimeStamp}}",//时间戳,自1970年以来的秒数"nonceStr": "{{.NonceStr}}",//随机串"package": "{{.Package}}","signType": "{{.SignType}}",//微信签名方式:"paySign": "{{.PaySign}}"   //微信签名},function (res) {if (res.err_msg == "get_brand_wcpay_request:ok") {alert("支付成功");}else if (res.err_msg == "get_brand_wcpay_request:cancel")  {alert("支付过程中用户取消");}else{//支付失败alert(res.err_msg)}}
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

业务流程

  • 用户通过不同场景点击进入商户网页

  • 用户选择商品购买,完成选购流程

  • 使用网页授权获取用户基本信息,得到openid

  • 商户使用统一下单接口获取prepay_id

  • 商户网页使用getBrandWCPayRequest接口调起微信支付

  • 支付成功后,在该接口里面会返回结果,同时微信也会发送异步通知到统一下单时候填写的notify_url

开发实现

实现目标目标

打开网页http://config.HOST/buy.html,选购商品,最终打开http://config.HOST/jsapi.html调起微信支付

JSAPI必须先用网页授权的方式去获取用户的openid,在统一下单的时候需要,详情可以查看官方文档:网页授权获取获取用户基本信息

创建jsapipay包

创建文件夹jsapipay

设置网页获取用户基本信息的授权域名

只有在授权域名下的链接才能获取openid,所以第一步就去设置网页授权目录

假设我们网站的域名为:www.qq.com,那么久需要把网页授权目录设置为www.qq.com

设置方法:登陆公众平台,在开发中中心,往下翻功能列表里面有一项:网页授权获取用户基本信息,点击旁边的修改按钮即可,按照要求填入我们要设置的域名

在本节代码里面我们把域名保存在config.HOST变量里面

创建选购商品显示页面

创建buy.html,点击里面的购买按钮后,获取code并跳转到支付页面buy.html

<!DOCTYPE html>
<html>
<title>商家网页</title>
<head>
<form class="editPart" action="{{.callbackurl}}"><fieldset><legend>商家网页</legend><p><label>商品金额1分钱测试</label></p><div class="lightEditor"><iframe id="myFrame" class="editorFrame" style="height:162px;" frameborder="0px" tabindex=3></iframe></div></p><input   type="submit" class="commentSubmit" value="点击购买" /></fieldset>
</form></body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

创建支付发起显示页面

创建jsapi.html文件,实现:

  • 实现对getBrandWCPayRequest接口的调用,从而调起微信支付
  • 打印出我们使用的参数

代码如下:


JSAPI支付一分钱

 <script type="text/javascript">//实现微信支付JS脚本function pay() {WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId": "{{.AppId}}",   //公众号名称,由商户传入"timeStamp": "{{.TimeStamp}}",//时间戳,自1970年以来的秒数"nonceStr": "{{.NonceStr}}",//随机串"package": "{{.Package}}","signType": "{{.SignType}}",//微信签名方式:"paySign": "{{.PaySign}}"   //微信签名},function (res) {if (res.err_msg == "get_brand_wcpay_request:ok") {alert("支付成功");}else if (res.err_msg == "get_brand_wcpay_request:cancel")  {alert("支付过程中用户取消");}else{//支付失败alert(res.err_msg)}});}</script>
</head><body><!--打印出参数-->
<h1>微信jsapi支付 1分钱</h1>
<a>Appid:   {{.AppId}}</a><br>
<a>TimeStamp:   {{.TimeStamp}}</a><br>
<a>Nonce_str:   {{.NonceStr}}</a><br>
<a>Package: {{.Package}}</a><br>
<a>SignType:    {{.SignType}}</a><br>
<a>PaySign: {{.PaySign}}</a><br><button type="button"  onclick="pay()">点击微信支付</button></body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

getBrandWCPayRequest接口参数生成

创建文件jsapirequest.go,实现

  • Jsapirequest结构体:存储getCPayReBrandWquest需要的参数,传递给jsapi.html页面
  • func (v *Jsapirequest) Signmd5()函数:对Jsapirequest结构体中的非空参数进行微信支付签名,并存储签名结果

代码如下:

package jsapipayimport ("encoding/xml""wechatpaygolang/config""wechatpaygolang/tools"
)//1.定义Jsapirequest结构体,存储getBrandWCPayRequest接口要使用的参数
type Jsapirequest struct {XMLName   xml.Name `xml:"xml"`AppId     string   `xml:"appId"`     //公众账号IDNonceStr  string   `xml:"nonceStr"`  //随机字符串Package   string   `xml:"package"`   //账单类型SignType  string   `xml:"signType"`  //商户号TimeStamp string   `xml:"timeStamp"` //对账单日起PaySign string `xml:"-"` //最终请求串}//2.对Jsapirequest的非空字段进行md5签名,并存储签名结构
func (v *Jsapirequest) Signmd5() bool {sign := tools.Wechatpay_SignMD5(*v, config.API_KEY)v.PaySign = signreturn true
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

获取openid

创建auth.go文件,实现

  • Resultauth结构体,存储获取到的y用户基本新消息
  • func Getopenid(w http.ResponseWriter, r *http.Request) (openid string)函数,根据code获取openid
  • func getauthurl(callurl string) string函数,生成网页授权获取code的url,code会回传给callurl,注意这里的callurl必须是
    urlencode编码

代码实现

package jsapipayimport ("fmt""wechatpaygolang/config""wechatpaygolang/tools"
)type Resultauth struct {Access_token string `json:"access_token"`Expires_in   int    `json:"expires_in"`Rfresh_token string `json:"rfresh_token"`Openid       string `json:"openid"`Scope        string `json:"scope"`
}//根据code获取openid
func Getopenid(code string) (openid string) {r.ParseForm()requestUrl := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + config.APP_ID + "&secret=" + config.APP_SECRET + "&code=" + code + "&grant_type=authorization_code"rebots := tools.Get(requestUrl)var m Resultautherr := tools.XmlDecodebytes(rebots, &m)if err != nil {fmt.Println("error:", err)}openid = m.Openidfmt.Println("openid=" + openid)return openid}// 获取code
func getauthurl(url string) string {str := "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx2b029c08a6232582&redirect_uri=" + url + "&response_type=code&scope=snsapi_base&state=test#wechat_redirect"return str}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

创建jsapi.go

前面我们分别创建了2个html页面,一个是表示选购页面,一个是发起支付页面,那么决定显示那个html页面,并传递对应的参数进去,在jsapi.go里面实现

func Jsapi(w http.ResponseWriter, r *http.Request)为页面入口函数,在这个函数里面,进行显示页面的判断和参数传递

  • 如果判断链接没有code字段,我们进入商品选购页面buy.html
  • 如果判断链接有code字段,我们进入支付页面pay.html,因为有code字段肯定是进行可buy.html里面的授权跳转

package jsapipayimport ("fmt""html/template""io/ioutil""net/http""os""wechatpaygolang/auth""wechatpaygolang/config""wechatpaygolang/tools""wechatpaygolang/unifiedorder"
)func Jsapi(w http.ResponseWriter, r *http.Request) {r.ParseForm()code := r.FormValue("code")//没有code·进入选购页面if code == "" {path, _ := os.Getwd()t, err := template.ParseFiles(path + "/jsapipay/buy.html")fmt.Println(err)m := map[string]string{}m["callbackurl"] = getauthurl("http://" + config.HOST + "/jsapi")da.Signmd5()t.Execute(w, da)} else {//获取openidopenid := auth.Getopenid(w, r)//1.统一下单v := &unifiedorder.Unifieldrequest{Appid: config.APP_ID, Mch_id: config.MCH_ID}//支付金额,单位为分v.Total_fee = "1"//商品说明v.Body = "JSAPI"//32位随机字符串v.Nonce_str = tools.Getnoncestr(32)//商户订单号,此处也随机生成v.Out_trade_no = tools.Getnoncestr(32)//发起支付的机器IPv.Spbill_create_ip = "127.0.0.1"//设置openidv.Openid = "omL67jm0A1sKwystTq7WsU28MF_c"//最终支付成功的通知地址v.Notify_url = config.URL_UNIFIEDORDER_NOTIFYURL//支付方式为JSAPIv.Trade_type = "JSAPI"//对上面设置的字段进行签名v.Signmd5()//把所有的有效字段组织为xml格式v.Xml()//向统一下单接口发起请求,并把返回请求结果res := v.Dorequest()fmt.Println("下单结果=", res.ReponseXML)fmt.Println("prepayid=", res.Prepay_id)fmt.Println("========================================")//打开支付网页,并传递参数,包括传递我们上面统一下单获取到的prepay_idpath, _ := os.Getwd()t, err := template.ParseFiles(path + "/jsapipay/pay.html")fmt.Println(err)da := Jsapirequest{AppId: config.APP_ID}da.Package = "prepay_id=" + res.Prepay_idda.TimeStamp = tools.Time_stamp_seconds()da.NonceStr = tools.Getnoncestr(32)da.SignType = "MD5"da.Signmd5()t.Execute(w, da)}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

结果判定

jsapi.html里面,根据判定结果,进行相应的处理

返回值 描述
get_brand_wcpay_request:ok  支付成功
get_brand_wcpay_request:cancel  支付过程中用户取消
get_brand_wcpay_request:fail    支付失败
  • 1
  • 2
  • 3
  • 4

和/jsapi地址关联

main.go文件里面

  • 加入头文件"wechatpaygolang/jsapi"

  • rout函数里面加入路由

func rout(w http.ResponseWriter, r *http.Request) {
r.ParseForm()path := r.URL.Pathif path == "/helloworld" {fmt.Println("被扫支付")helloworld.HelloWorld(w, r)} else if path == "/micropay" {fmt.Println("被扫支付")micropay.Micropay(w, r)} else if path == "/jsapi" {fmt.Println("被扫支付")jsapi.Jsapi(w, r)} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

设置支付目录

jsapi必须设置支付木有,只有在支付目录下的页面才能发起支付,否则会报错,上异步我们已经确认了我们要访问的地址为/jsapi,假设我们的域
名为www.qq.com,那么这个时候我们的支付域名就是www.qq.com/jsapi,那么我们就需要把www.paytest.com/设置为支付目录

设置方法:
登陆公众平台-微信支付-开发配置-JSAPI支付,添加支付目录为www.paytest.com/,注意添加的目录的域名必须经过备案

同时可以设置测试目录,测试目录不需要备案,但必须把测试的微信号加入白名单,而且测试的支付链接只能在这个公众号内打开

编译测试

在微信里面打开支付url,进行测试

异步通知

除了上面js接口里面的结果判定,同时在统一下单的时候,我们填写了一个notify_url,我们同时会发送异步通知到这个地址,这个后面再说,因为还有其他支付方式也会发送异步通知,所以作为一个单独模块来说,这里我们先随便填一个,无所谓的。

这篇关于微信支付之JSAPI支付的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1009161

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

基于微信小程序与嵌入式系统的智能小车开发(详细流程)

一、项目概述 本项目旨在开发一款智能小车,结合微信小程序与嵌入式系统,提供实时图像处理与控制功能。用户可以通过微信小程序远程操控小车,并实时接收摄像头采集的图像。该项目解决了传统遥控小车在图像反馈和控制延迟方面的问题,提升了小车的智能化水平,适用于教育、科研和娱乐等多个领域。 二、系统架构 1. 系统架构设计 本项目的系统架构主要分为以下几个部分: 微信小程序:负责用户界面、控制指令的

微信小程序uniappvue3版本-控制tabbar某一个的显示与隐藏

1. 首先在pages.json中配置tabbar信息 2. 在代码根目录下添加 tabBar 代码文件 直接把微信小程序文档里面的四个文件复制到自己项目中就可以了   3. 根据自己的需求更改index.js文件 首先我这里需要判断什么时候隐藏某一个元素,需要引入接口 然后在切换tabbar时,改变tabbar当前点击的元素 import getList from '../

微信小程序(一)数据流与数据绑定

一、单向数据流和双向数据流 1、单项数据流:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面 优点:数据跟踪方便,流向单一,追寻问题比较方便【主要体现:微信小程序】。 缺点:就是写起来不太方便,如果修改UI界面数据需要维护对应的model对象 2、双向数据流:值和UI是双向绑定的,大家都知道,只要UI里面的值发生

微信小程序学习网站

小程序--柯神博客 http://www.cnblogs.com/nosqlcoco 案例地址: https://github.com/cocoli/weixin_smallexe/tree/master/weixin_demo/pages/component/uploadfile

分享一个基于uniapp科技馆服务微信小程序 博物馆管理小程序(源码、调试、LW、开题、PPT)

💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流! 💕💕学习资料、程序开发、技术解答、文档报告 💕💕如需要源码,可以扫取文章下方二维码联系咨询 💕💕Java项目 💕💕微信小程序项目 💕💕Android项目 �

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题 GitHub Pages是一个直接从GitHub存储库托管的静态站点服务,‌它允许用户通过简单的配置,‌将个人的代码项目转化为一个可以在线访问的网站。‌这里使用flutter build web来构建web发布到GitHub Pages。 最近通过flutter build web,通过发布到GitHu

1-3 微信小程序协同工作和发布

协同工作和发布 🥟🥞以权限管理需求为例 一个项目组,一般有不同的岗位,不同角色的员工同时参与项目成员 流程 成员管理的两个方面 不同项目成员对应的权限 版本

Deepin Linux 下安装微信

在下载和运行这个项目之前,你需要在电脑上安装Git和Node.js (来自npm)。在命令行中输入: 安装Git和nodejs 命令:sudo apt-get install git  sudo apt-get install nodejs 执行完上面命令之后运行下面命令 # 下载仓库 git clone https://github.com/geeeeeeeeek/elec