跳至主要内容

微信支付的坑(2)

微信支付的坑(2)

上一篇支付相关的博客中,我们介绍了接入支付宝和微信支付的两个大坑,一个是沙箱测试环境的搭建,第二个是回调接口的编写。在这篇中,我们将继续深入。

如果你需要接入微信手机端的网页支付的话,光接入“H5支付”产品是不够的,因为H5支付只能用于微信外的手机网页支付,如果想要在微信内扫一扫,打开页面然后支付,需要使用“公众号支付”产品。而“公众号支付”产品要比H5支付复杂许多。

首先,在H5支付下单后,后端只要返回一个带有回调的链接就可以实现唤起微信支付,并且在支付完成后回到相应的页面。而公众号支付支付需要前端拿到后端的返回值(prepare_id)之后,再进行一次带有签名的请求。由于不可能将秘钥等敏感数据传递或放置于前端,所以需要后端进行请求的签名,然后将所有参数发送到前端,由前端请求。

而且,在初识请求后端生成prepare_id到时候,需要一个不同的参数,即openid。openid是一个用户的标识,但是这个标识不是一个全局的userid,而是一个用户相对于某个微信应用(appid)生成的id。为了获取openid需要使用微信的oauth鉴权接口,不过在进行开发之前,需要进行一系列的配置(不得不说,微信的配置要比支付宝繁杂很多。并且就接口友好性、SDK支持,社区和官方帮助等方面的对比,支付宝的开放性,要比微信好很多)

设置支付目录

在微信商户平台(pay.weixin.qq.com)设置您的公众号支付支付目录,设置路径:商户平台–>产品中心–>开发配置,如图7.7所示。公众号支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。
现在已经支持配置根目录,配置后有一定的生效时间,一般5分钟内生效

需要注意的是公众平台有时候设置的是域名(url),不能加协议,而有时候填写的是链接,要加协议(http或https)

设置授权回调域名

除了设置支付目录,为了获取openid,需要设置授权回调域名(公众平台->设置->公众号设置->网页授权域名):

开发公众号支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败

注意:在获取公众平台AppID的同时,也要获取App Secret,这个跟微信商户平台Api Secret是不同的。

开发

配置之后,开发流程就比较简单了

  • 前端请求微信,获取用户授权后,回调我们之前配置的域名下的一个地址:
curl 'https://open.weixin.qq.com/connect/oauth2/authorize?
appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect' 
# 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
# 因为我们只要获取openid,所以可以scope可以使用snsapi_base,可以静默授权,无需用户同意
# 之后页面将跳转至 redirect_uri/?code=CODE&state=STATE
  • 微信回调我们的redirect_uri(我们使用一个前端的地址作为这个uri),前端拿到回调中的code之后,在支付的时候一同传递给后端;
  • 后端使用code, appid, secret等请求微信,换取openid
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
  • 使用openid和其他支付参数,使用统一下单api请求获取prepare_id
  • 使用秘钥签名前端需要的请求,将sign和参数一同返回给前端

Ref

Written with StackEdit.

评论

  1. Casino Resort in Elgin, IL - Mapyro
    The Casino is a fun and 논산 출장샵 easy to 제천 출장안마 drive vacation destination. You 경주 출장마사지 will enjoy the full range of 김포 출장안마 casino gaming, poker, dining 김천 출장안마 and entertainment in our lively dining

    回复删除

发表评论

此博客中的热门博文

Spring Boot: Customize Environment

Spring Boot: Customize Environment Environment variable is a very commonly used feature in daily programming: used in init script used in startup configuration used by logging etc In Spring Boot, all environment variables are a part of properties in Spring context and managed by Environment abstraction. Because Spring Boot can handle the parse of configuration files, when we want to implement a project which uses yml file as a separate config file, we choose the Spring Boot. The following is the problems we met when we implementing the parse of yml file and it is recorded for future reader. Bind to Class Property values can be injected directly into your beans using the @Value annotation, accessed via Spring’s Environment abstraction or bound to structured objects via @ConfigurationProperties. As the document says, there exists three ways to access properties in *.properties or *.yml : @Value : access single value Environment : can access multi

Elasticsearch: Join and SubQuery

Elasticsearch: Join and SubQuery Tony was bothered by the recent change of search engine requirement: they want the functionality of SQL-like join in Elasticsearch! “They are crazy! How can they think like that. Didn’t they understand that Elasticsearch is kind-of NoSQL 1 in which every index should be independent and self-contained? In this way, every index can work independently and scale as they like without considering other indexes, so the performance can boost. Following this design principle, Elasticsearch has little related supports.” Tony thought, after listening their requirements. Leader notice tony’s unwillingness and said, “Maybe it is hard to do, but the requirement is reasonable. We need to search person by his friends, didn’t we? What’s more, the harder to implement, the more you can learn from it, right?” Tony thought leader’s word does make sense so he set out to do the related implementations Application-Side Join “The first implementation

Implement isdigit

It is seems very easy to implement c library function isdigit , but for a library code, performance is very important. So we will try to implement it and make it faster. Function So, first we make it right. int isdigit ( char c) { return c >= '0' && c <= '9' ; } Improvements One – Macro When it comes to performance for c code, macro can always be tried. #define isdigit (c) c >= '0' && c <= '9' Two – Table Upper version use two comparison and one logical operation, but we can do better with more space: # define isdigit(c) table[c] This works and faster, but somewhat wasteful. We need only one bit to represent true or false, but we use a int. So what to do? There are many similar functions like isalpha(), isupper ... in c header file, so we can combine them into one int and get result by table[c]&SOME_BIT , which is what source do. Source code of ctype.h : # define _ISbit(bit) (1 << (