-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path微信支付demo示例.html
220 lines (137 loc) · 14.6 KB
/
微信支付demo示例.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
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
<!DOCTYPE html><html><head><title>微信支付demo示例</title><meta charset='utf-8'><link href='https://cdn.maxiang.io/res-min/themes/marxico.css' rel='stylesheet'><style></style></head><body><div id='preview-contents' class='note-content'>
<h1 id="微信支付demo示例">微信支付demo示例</h1>
<p>微信支付nodejs demo</p>
<h3 id="开发步骤">开发步骤</h3>
<h5 id="1-引入扩展包">1. 引入扩展包</h5>
<h6 id="11-appextendutiljs-常用工具类库">1.1 app/extend/util.js (常用工具类库)</h6>
<h6 id="12-appextendwxpayjs-微信支付类库">1.2 app/extend/wxpay.js (微信支付类库)</h6>
<h5 id="2-packagesjson-添加-微信支付依赖包">2. packages.json 添加 微信支付依赖包</h5>
<pre class="prettyprint hljs-dark"><code class="hljs xquery"><div class="hljs-line"><span class="hljs-string">"dependencies"</span>: {
</div><div class="hljs-line"> <span class="hljs-string">"MD5"</span>: <span class="hljs-string">"^1.2.1"</span>,
</div><div class="hljs-line"> <span class="hljs-string">"request"</span>: <span class="hljs-string">"^2.88.0"</span>,
</div><div class="hljs-line"> <span class="hljs-string">"body-parser"</span>: <span class="hljs-string">"^1.18.3"</span>,
</div><div class="hljs-line"> <span class="hljs-string">"xml2js"</span>: <span class="hljs-string">"^0.4.6"</span>
</div><div class="hljs-line">},
</div></code></pre>
<h5 id="3-mpn-install-导入依赖包">3. mpn install 导入依赖包</h5>
<h5 id="4-在要使用的文件里添加微信支付声明-appcontrollerhomejs">4. 在要使用的文件里,添加微信支付声明 app/controller/home.js</h5>
<pre class="prettyprint hljs-dark"><code class="hljs javascript"><div class="hljs-line"><span class="hljs-comment">//引入微信支付插件 (注意插件路径和文件路径)</span>
</div><div class="hljs-line"><span class="hljs-keyword">const</span> WXPay = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../extend/wxpay'</span>);
</div><div class="hljs-line"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
</div><div class="hljs-line"><span class="hljs-keyword">const</span> wxpay = WXPay({
</div><div class="hljs-line"> <span class="hljs-attr">appid</span>: <span class="hljs-string">'公众号ID'</span>,
</div><div class="hljs-line"> <span class="hljs-attr">mch_id</span>: <span class="hljs-string">'商户号ID'</span>,
</div><div class="hljs-line"> <span class="hljs-attr">partner_key</span>: <span class="hljs-string">'商户密钥(证书密码)'</span>,
</div><div class="hljs-line"> <span class="hljs-attr">pfx</span>: fs.readFileSync(<span class="hljs-string">'././证书路径.p12'</span>),
</div><div class="hljs-line">});
</div></code></pre>
<h5 id="5-在要使用的方法里进行调用">5. 在要使用的方法里,进行调用</h5>
<h5 id="51-创建扫码支付非固定二维码统一下单接口">5.1 创建扫码支付(非固定二维码,统一下单接口)</h5>
<pre class="prettyprint hljs-dark"><code class="hljs less"><div class="hljs-line"><span class="hljs-selector-tag">wxpay</span><span class="hljs-selector-class">.createUnifiedOrder</span>({
</div><div class="hljs-line"> <span class="hljs-attribute">body</span>: <span class="hljs-string">'扫码支付测试'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">out_trade_no</span>: <span class="hljs-string">'API2019010100001003'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">total_fee</span>: <span class="hljs-number">1</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">spbill_create_ip</span>: <span class="hljs-string">'192.168.2.210'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">notify_url</span>: <span class="hljs-string">'http://mp.ngrok.xiaomiqiu.cn/receive/wxReceive'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">trade_type</span>: <span class="hljs-string">'NATIVE'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">product_id</span>: <span class="hljs-string">'1234567890'</span>
</div><div class="hljs-line">}, <span class="hljs-selector-tag">function</span> (err, result) {
</div><div class="hljs-line"> <span class="hljs-comment">// 接口返回信息,判断是否创建订单成功</span>
</div><div class="hljs-line"> <span class="hljs-selector-tag">console</span><span class="hljs-selector-class">.log</span>(result);
</div><div class="hljs-line">});
</div></code></pre>
<h5 id="52-创建扫码支付固定二维码">5.2 创建扫码支付(固定二维码)</h5>
<pre class="prettyprint hljs-dark"><code class="hljs qml"><div class="hljs-line"><span class="hljs-comment">//提供一个生成支付二维码链接的函数,把url生成二维码给用户扫</span>
</div><div class="hljs-line"><span class="hljs-built_in">var</span> <span class="hljs-built_in">url</span> = wxpay.createMerchantPrepayUrl({ <span class="hljs-attribute">product_id</span>: <span class="hljs-string">'123456'</span> });
</div><div class="hljs-line"><span class="hljs-comment">//商户后台收到微信的回调之后,</span>
</div><div class="hljs-line"><span class="hljs-comment">//调用 createUnifiedOrder() 生成预支付交易单</span>
</div><div class="hljs-line"><span class="hljs-comment">//将结果的XML数据返回给微信。</span>
</div></code></pre>
<h5 id="53-创建公众号支付jsapi小程序支付相同">5.3 创建公众号支付(JSAPI,小程序支付相同)</h5>
<pre class="prettyprint hljs-dark"><code class="hljs less"><div class="hljs-line"><span class="hljs-comment">//后台调用</span>
</div><div class="hljs-line"><span class="hljs-selector-tag">wxpay</span><span class="hljs-selector-class">.getBrandWCPayRequestParams</span>({
</div><div class="hljs-line"> <span class="hljs-attribute">openid</span>: <span class="hljs-string">'微信用户 openid'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">body</span>: <span class="hljs-string">'公众号支付测试'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">detail</span>: <span class="hljs-string">'公众号支付测试'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">out_trade_no</span>: <span class="hljs-string">'20150331'</span>+Math.random().toString().substr(<span class="hljs-number">2</span>, <span class="hljs-number">10</span>),
</div><div class="hljs-line"> <span class="hljs-attribute">total_fee</span>: <span class="hljs-number">1</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">spbill_create_ip</span>: <span class="hljs-string">'192.168.2.210'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">notify_url</span>: <span class="hljs-string">'http://wxpay_notify_url'</span>
</div><div class="hljs-line">}, <span class="hljs-selector-tag">function</span>(err, result){
</div><div class="hljs-line"> <span class="hljs-comment">// in express</span>
</div><div class="hljs-line"> <span class="hljs-selector-tag">res</span><span class="hljs-selector-class">.render</span>(<span class="hljs-string">'wxpay/jsapi'</span>, { <span class="hljs-attribute">payargs</span>:result })
</div><div class="hljs-line"> <span class="hljs-comment">// in egg</span>
</div><div class="hljs-line"> <span class="hljs-selector-tag">await</span> <span class="hljs-selector-tag">ctx</span><span class="hljs-selector-class">.render</span>(<span class="hljs-string">'wxpay/jsapi'</span>, { <span class="hljs-attribute">payargs</span>:result });
</div><div class="hljs-line">});
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-comment">//网页调用参数(以ejs为例)</span>
</div><div class="hljs-line"><span class="hljs-selector-tag">WeixinJSBridge</span><span class="hljs-selector-class">.invoke</span>(
</div><div class="hljs-line"> <span class="hljs-string">"getBrandWCPayRequest"</span>, <%-JSON.stringify(payargs)%>, function(res){
</div><div class="hljs-line"> <span class="hljs-selector-tag">if</span>(res.err_msg == <span class="hljs-string">"get_brand_wcpay_request:ok"</span> ) {
</div><div class="hljs-line"> <span class="hljs-comment">// success</span>
</div><div class="hljs-line"> }
</div><div class="hljs-line">});
</div></code></pre>
<h5 id="54-通过商户订单号查询支付结果">5.4 通过商户订单号查询支付结果</h5>
<pre class="prettyprint hljs-dark"><code class="hljs javascript"><div class="hljs-line">wxpay.queryOrder({
</div><div class="hljs-line"> <span class="hljs-attr">out_trade_no</span>:<span class="hljs-string">"API2019010100001003"</span>
</div><div class="hljs-line">}, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, order</span>)</span>{
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(order);
</div><div class="hljs-line">});
</div></code></pre>
<h5 id="55-通过商户订单号进行订单退款">5.5 通过商户订单号进行订单退款</h5>
<pre class="prettyprint hljs-dark"><code class="hljs less"><div class="hljs-line"><span class="hljs-selector-tag">wxpay</span><span class="hljs-selector-class">.refundOrder</span>({
</div><div class="hljs-line"> <span class="hljs-attribute">out_trade_no</span>: <span class="hljs-string">'API2019010100001003'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">total_fee</span>: <span class="hljs-number">1</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">refund_fee</span>: <span class="hljs-number">1</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">notify_url</span>: <span class="hljs-string">'http://mp.ngrok.xiaomiqiu.cn/receive/wxRefund'</span>,
</div><div class="hljs-line"> <span class="hljs-attribute">out_refund_no</span>: <span class="hljs-string">'RFD2019010100001002'</span>
</div><div class="hljs-line">}, <span class="hljs-selector-tag">function</span>(err, result){
</div><div class="hljs-line"> <span class="hljs-selector-tag">console</span><span class="hljs-selector-class">.log</span>(result);
</div><div class="hljs-line">});
</div></code></pre>
<h4 id="6-回调功能">6 回调功能</h4>
<h5 id="61-服务端处理微信的回调express为例">6.1 服务端处理微信的回调(express为例)</h5>
<pre class="prettyprint hljs-dark"><code class="hljs javascript"><div class="hljs-line"><span class="hljs-comment">// 6.1 支付结果异步通知</span>
</div><div class="hljs-line">app.use(<span class="hljs-string">'/receive/wxReceive'</span>, wxpay.useWXCallback(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">msg, req, res, next</span>)</span>{
</div><div class="hljs-line"> <span class="hljs-comment">// 处理商户业务逻辑</span>
</div><div class="hljs-line"> <span class="hljs-comment">// res.success() 向微信返回处理成功信息,res.fail()返回失败信息。</span>
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"收到支付回调"</span>);
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(msg);
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(req);
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(res);
</div><div class="hljs-line"> res.success();
</div><div class="hljs-line">}));
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"><span class="hljs-number">6.2</span> 退款回调同支付回调。
</div></code></pre>
<h5 id="62-服务端处理微信的回调egg为例">6.2 服务端处理微信的回调(egg为例)</h5>
<pre class="prettyprint hljs-dark"><code class="hljs javascript"><div class="hljs-line"><span class="hljs-number">6.2</span><span class="hljs-number">.1</span> 首先添加中间件 app/middleware/xmlparse.js
</div><div class="hljs-line"><span class="hljs-number">6.2</span><span class="hljs-number">.2</span> 然后启用中间件 config/config.default.js
</div><div class="hljs-line"> 添加: exports.middleware = [<span class="hljs-string">'xmlparse'</span>];
</div><div class="hljs-line"><span class="hljs-number">6.2</span><span class="hljs-number">.3</span> 路由中配置中间件 app/router.js
</div><div class="hljs-line"> <span class="hljs-keyword">const</span> {router, controller, middleware} = app;
</div><div class="hljs-line"> router.post(<span class="hljs-string">'/receive/wxReceive'</span>, middleware.xmlparse(), controller.home.wxReceive);
</div><div class="hljs-line"><span class="hljs-number">6.2</span><span class="hljs-number">.4</span> 然后就可以在 app/controller/home.js 里写收到回调的处理了
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"> <span class="hljs-keyword">async</span> wxReceive() {
</div><div class="hljs-line"> <span class="hljs-keyword">const</span> { ctx } = <span class="hljs-keyword">this</span>;
</div><div class="hljs-line"><wbr>
</div><div class="hljs-line"> <span class="hljs-comment">// 支付结果异步通知</span>
</div><div class="hljs-line"> wxpay.eggWXCallback(ctx.req, ctx.res, ctx.next, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">msg, req, res, next</span>)</span>{
</div><div class="hljs-line"> <span class="hljs-comment">// 处理商户业务逻辑</span>
</div><div class="hljs-line"> <span class="hljs-comment">// res.success() 向微信返回处理成功信息,res.fail()返回失败信息。</span>
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"收到支付回调"</span>);
</div><div class="hljs-line"> <span class="hljs-built_in">console</span>.log(msg);
</div><div class="hljs-line"> res.success();
</div><div class="hljs-line"> });
</div><div class="hljs-line"> }
</div><div class="hljs-line"><span class="hljs-number">6.2</span><span class="hljs-number">.5</span> 退款回调同支付回调。
</div></code></pre>
<h4 id="遇到的问题">遇到的问题:</h4>
<p>1.request 请求总是失败:报错说不认识 toString() <br>
问题原因:证书路径.p12 是一个空的,需要使用真实证书和对应的 微信支付key mch_id app_id等。 <br>
2.支付回调请求总是无法解析,报错 stream.on 不是一个 action <br>
问题原因: <br>
2.1 没有使用中间件,xmlparse.js <br>
2.2 没有使用接收到的 this.ctx.req 传入 wxpay.js 里做处理(问题已修复)。</p></div></body></html>