├── .gitignore
├── README.md
├── example
├── backOrderQueryTest.py
├── backOrderTest.py
├── queryOrderTest.py
├── refundTest.py
└── tradeTest.py
└── ipaynowPythonSdk
├── ipaynow
├── __init__.py
├── error.py
├── interface.py
├── jsonParseFaced.py
├── md5Faced.py
├── packMsg.py
├── paramlist.py
├── queryOrder.py
├── refund.py
├── trade.py
├── unpackMsg.py
├── utils.py
└── version.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | \.idea/
3 |
4 | ipaynowPythonSdk/ipaynow\.egg-info/
5 |
6 | ipaynowPythonSdk/dist/
7 |
8 | ipaynowPythonSdk/build/
9 |
10 | ipaynowPythonSdk/ipaynow/__pycache__/
11 |
12 | ipaynow_pay_python\.rar
13 |
14 | .idea
15 | example/__pycache__/
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # 聚合支付SDK使用说明 #
3 |
4 | ## 版本变更记录 ##
5 |
6 | - 1.0.0 : 初稿
7 | - 1.0.1 :接口按渠道分开,增加微信支付宝外的渠道方法
8 |
9 | ## 目录 ##
10 |
11 | [1. 概述](#1)
12 |
13 | [1.1 简介](#1.1)
14 |
15 | [1.2 如何获取](#1.2)
16 |
17 | [1.3 使用说明](#1.3)
18 |
19 | [2. API](#2)
20 |
21 | [2.1 聚合交易API](#2.1)
22 |
23 | [微信被扫支付](#2.1.1)
24 |
25 | [支付宝被扫支付](#2.1.2)
26 |
27 | [手Q被扫支付](#2.1.3)
28 |
29 | [京东被扫支付](#2.1.4)
30 |
31 | [银联被扫支付](#2.1.5)
32 |
33 | [微信主扫支付](#2.1.6)
34 |
35 | [支付宝主扫支付](#2.1.7)
36 |
37 | [手Q主扫支付](#2.1.8)
38 |
39 | [京东主扫支付](#2.1.9)
40 |
41 | [银联主扫支付](#2.1.10)
42 |
43 | [微信公众号支付](#2.1.11)
44 |
45 | [支付宝公众号支付](#2.1.13)
46 |
47 | [手Q公众号支付](#2.1.15)
48 |
49 | [微信H5](#2.1.17)
50 |
51 | [支付宝H5](#2.1.18)
52 |
53 | [银联H5](#2.1.19)
54 |
55 | [招行一网通H5](#2.1.20)
56 |
57 | [手Q H5](#2.1.21)
58 |
59 | [支付宝网页web](#2.1.22)
60 |
61 | [银联网页web](#2.1.23)
62 |
63 | [微信小程序支付](#2.1.24)
64 |
65 | [2.2 支付结果通知](#2.2)
66 |
67 | [2.3 订单查询API](#2.3)
68 |
69 | [用户主扫支付订单查询](#2.3.1)
70 |
71 | [用户被扫支付订单查询](#2.3.2)
72 |
73 | [商户公众号支付订单查询](#2.3.3)
74 |
75 | [商户H5支付订单查询](#2.3.4)
76 |
77 | [商户网页支付订单查询](#2.3.5)
78 |
79 | [商户微信App支付订单查询](#2.3.6)
80 |
81 | [2.4 退款API](#2.4)
82 |
83 | [退款](#2.4.1)
84 |
85 | [退款查询](#2.4.2)
86 |
87 | [撤销](#2.4.3)
88 |
89 | [撤销查询](#2.4.4)
90 |
91 |
92 |
1. 概述
93 | 1.1 简介
94 |
95 | - 聚合支付SDK Python版本,请使用Python3 。
96 |
97 | 1.2 如何获取
98 |
99 |
100 | [demo源码](https://github.com/ipaynowORG/ipaynow_pay_python.git)
101 |
102 | 1.3 使用说明
103 |
104 | 使用方法:
105 |
106 | 您可以从 GitHub 上下载 Python SDK 的源代码:
107 |
108 | git clone https://github.com/ipaynowORG/ipaynow_pay_python.git
109 |
110 | 1.cd 进入ipaynowPythonSdk 文件夹
111 | 2.执行 "python setup.py install"
112 | 3.在代码中 import ipaynow
113 | 参考示例代码
114 | 示例代码
115 | cd 进入example文件夹
116 | 运行 python tradeTest.py
117 |
118 |
119 |
120 | 2. API
121 |
122 | 2.1 聚合交易API
123 |
124 | 交易模块:trade.py
125 |
126 |
127 |
128 | - 微信被扫支付
129 |
130 | '''
131 | 微信被扫支付
132 | appId:商户应用id
133 | appKey:商户应用秘钥
134 | mhtOrderDetail:订单详情
135 | notifyUrl:商户后台通知URL
136 | amt:订单金额单位分,默认1分
137 | orderno:订单号(默认系统时间)
138 | channelAuthCode ; 支付授权码
139 | isTest 是否测试 True 测试环境 False 生产环境
140 | '''
141 | def wx_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
142 |
143 |
144 |
145 | - 支付宝被扫支付
146 |
147 | '''
148 | 支付宝被扫支付
149 | appId:商户应用id
150 | appKey:商户应用秘钥
151 | mhtOrderDetail:订单详情
152 | notifyUrl:商户后台通知URL
153 | amt:订单金额单位分,默认1分
154 | orderno:订单号(默认系统时间)
155 | channelAuthCode ; 支付授权码
156 | isTest 是否测试 True 测试环境 False 生产环境
157 | '''
158 | def ali_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
159 |
160 |
161 | - 手Q被扫支付
162 |
163 | '''
164 | 手Q被扫支付
165 | appId:商户应用id
166 | appKey:商户应用秘钥
167 | mhtOrderDetail:订单详情
168 | notifyUrl:商户后台通知URL
169 | amt:订单金额单位分,默认1分
170 | orderno:订单号(默认系统时间)
171 | channelAuthCode ; 支付授权码
172 | isTest 是否测试 True 测试环境 False 生产环境
173 | '''
174 | def handq_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
175 |
176 |
177 |
178 | - 京东被扫支付
179 |
180 | '''
181 | 京东被扫支付
182 | appId:商户应用id
183 | appKey:商户应用秘钥
184 | mhtOrderDetail:订单详情
185 | notifyUrl:商户后台通知URL
186 | amt:订单金额单位分,默认1分
187 | orderno:订单号(默认系统时间)
188 | channelAuthCode ; 支付授权码
189 | isTest 是否测试 True 测试环境 False 生产环境
190 | '''
191 | def jd_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isest=True)
192 |
193 |
194 |
195 | - 银联被扫支付
196 |
197 | '''
198 | 银联被扫支付
199 | appId:商户应用id
200 | appKey:商户应用秘钥
201 | mhtOrderDetail:订单详情
202 | notifyUrl:商户后台通知URL
203 | amt:订单金额单位分,默认1分
204 | orderno:订单号(默认系统时间)
205 | channelAuthCode ; 支付授权码
206 | isTest 是否测试 True 测试环境 False 生产环境
207 | '''
208 | def union_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest)
209 |
210 |
211 | - 微信主扫支付
212 |
213 | '''
214 | 微信主扫支付
215 | appId:商户应用id
216 | appKey:商户应用秘钥
217 | mhtOrderDetail:订单详情
218 | notifyUrl:商户后台通知URL
219 | amt:订单金额单位分,默认1分
220 | orderno:订单号(默认系统时间)
221 | outputType ; 0 返回二维码串 1 返回支付链接
222 | isTest 是否测试 True 测试环境 False 生产环境
223 | '''
224 | def wx_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True)
225 |
226 |
227 | - 支付宝主扫支付
228 |
229 | '''
230 | 支付宝主扫支付
231 | appId:商户应用id
232 | appKey:商户应用秘钥
233 | mhtOrderDetail:订单详情
234 | notifyUrl:商户后台通知URL
235 | amt:订单金额单位分,默认1分
236 | orderno:订单号(默认系统时间)
237 | outputType ; 0 返回二维码串 1 返回支付链接
238 | isTest 是否测试 True 测试环境 False 生产环境
239 | '''
240 | def ali_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True)
241 |
242 |
243 | - 手Q主扫支付
244 |
245 | '''
246 | 手Q主扫支付
247 | appId:商户应用id
248 | appKey:商户应用秘钥
249 | mhtOrderDetail:订单详情
250 | notifyUrl:商户后台通知URL
251 | amt:订单金额单位分,默认1分
252 | orderno:订单号(默认系统时间)
253 | outputType ; 0 返回二维码串 1 返回支付链接
254 | isTest 是否测试 True 测试环境 False 生产环境
255 | '''
256 | def handq_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True)
257 |
258 |
259 | - 京东主扫支付
260 |
261 | '''
262 | 京东主扫支付
263 | appId:商户应用id
264 | appKey:商户应用秘钥
265 | mhtOrderDetail:订单详情
266 | notifyUrl:商户后台通知URL
267 | amt:订单金额单位分,默认1分
268 | orderno:订单号(默认系统时间)
269 | outputType ; 0 返回二维码串 1 返回支付链接
270 | isTest 是否测试 True 测试环境 False 生产环境
271 | '''
272 | def jd_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True)
273 |
274 |
275 | - 银联主扫支付
276 |
277 | '''
278 | 银联主扫支付
279 | appId:商户应用id
280 | appKey:商户应用秘钥
281 | mhtOrderDetail:订单详情
282 | notifyUrl:商户后台通知URL
283 | amt:订单金额单位分,默认1分
284 | orderno:订单号(默认系统时间)
285 | outputType ; 0 返回二维码串 1 返回支付链接
286 | isTest 是否测试 True 测试环境 False 生产环境
287 | '''
288 | def union_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True)
289 |
290 |
291 | - 微信公众号支付
292 |
293 | '''
294 | 微信公众号支付
295 | appId:商户应用id
296 | appKey:商户应用秘钥
297 | mhtOrderDetail:订单详情
298 | notifyUrl:商户后台通知URL
299 | frontNotifyUrl :商户前台通知URL
300 | amt:订单金额单位分,默认1分
301 | orderno:订单号(默认系统时间)
302 | outputType ; 0-公众号0模式
303 | isTest 是否测试 True 测试环境 False 生产环境
304 | '''
305 | def wx_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
306 |
307 |
308 |
309 | - 支付宝公众号支付
310 |
311 | '''
312 | 支付宝公众号支付
313 | appId:商户应用id
314 | appKey:商户应用秘钥
315 | mhtOrderDetail:订单详情
316 | notifyUrl:商户后台通知URL
317 | frontNotifyUrl :商户前台通知URL
318 | amt:订单金额单位分,默认1分
319 | orderno:订单号(默认系统时间)
320 | outputType ; 0-公众号0模式
321 | isTest 是否测试 True 测试环境 False 生产环境
322 | '''
323 | def ali_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
324 |
325 |
326 |
327 | - 手Q公众号支付
328 |
329 | '''
330 | 手Q公众号支付
331 | appId:商户应用id
332 | appKey:商户应用秘钥
333 | mhtOrderDetail:订单详情
334 | notifyUrl:商户后台通知URL
335 | frontNotifyUrl :商户前台通知URL
336 | amt:订单金额单位分,默认1分
337 | orderno:订单号(默认系统时间)
338 | outputType ; 0-公众号0模式
339 | isTest 是否测试 True 测试环境 False 生产环境
340 | '''
341 | def handq_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
342 |
343 |
344 |
345 | - 微信H5
346 |
347 | '''
348 | 微信H5支付
349 | appId:商户应用id
350 | appKey:商户应用秘钥
351 | mhtOrderDetail:订单详情
352 | notifyUrl:商户后台通知URL
353 | frontNotifyUrl :商户前台通知URL
354 | amt:订单金额单位分,默认1分
355 | orderno:订单号(默认系统时间)
356 | outputType ; 0-公众号0模式
357 | isTest 是否测试 True 测试环境 False 生产环境
358 | '''
359 | def wx_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
360 |
361 |
362 | - 支付宝H5
363 |
364 | '''
365 | 支付宝H5支付
366 | appId:商户应用id
367 | appKey:商户应用秘钥
368 | mhtOrderDetail:订单详情
369 | notifyUrl:商户后台通知URL
370 | frontNotifyUrl :商户前台通知URL
371 | amt:订单金额单位分,默认1分
372 | orderno:订单号(默认系统时间)
373 | outputType ; 0-公众号0模式
374 | isTest 是否测试 True 测试环境 False 生产环境
375 | '''
376 | def ali_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
377 |
378 |
379 | - 银联H5
380 |
381 | '''
382 | 银联H5支付
383 | appId:商户应用id
384 | appKey:商户应用秘钥
385 | mhtOrderDetail:订单详情
386 | notifyUrl:商户后台通知URL
387 | frontNotifyUrl :商户前台通知URL
388 | amt:订单金额单位分,默认1分
389 | orderno:订单号(默认系统时间)
390 | outputType ; 0-公众号0模式
391 | isTest 是否测试 True 测试环境 False 生产环境
392 | '''
393 | def union_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
394 |
395 |
396 | - 招行一网通H5
397 |
398 | '''
399 | 招行一网通 H5支付
400 | appId:商户应用id
401 | appKey:商户应用秘钥
402 | mhtOrderDetail:订单详情
403 | notifyUrl:商户后台通知URL
404 | frontNotifyUrl :商户前台通知URL
405 | amt:订单金额单位分,默认1分
406 | orderno:订单号(默认系统时间)
407 | outputType ; 0-公众号0模式
408 | isTest 是否测试 True 测试环境 False 生产环境
409 | '''
410 | def cmbywt_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
411 |
412 |
413 |
414 |
415 | - 手Q H5
416 |
417 | '''
418 | 手Q H5支付
419 | appId:商户应用id
420 | appKey:商户应用秘钥
421 | mhtOrderDetail:订单详情
422 | notifyUrl:商户后台通知URL
423 | frontNotifyUrl :商户前台通知URL
424 | amt:订单金额单位分,默认1分
425 | orderno:订单号(默认系统时间)
426 | outputType ; 0-公众号0模式
427 | isTest 是否测试 True 测试环境 False 生产环境
428 | '''
429 | def handq_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True)
430 |
431 |
432 | - 支付宝网页web
433 |
434 | '''
435 | 支付宝网页web支付
436 | appId:商户应用id
437 | appKey:商户应用秘钥
438 | mhtOrderDetail:订单详情
439 | notifyUrl:商户后台通知URL
440 | frontNotifyUrl :商户前台通知URL
441 | amt:订单金额单位分,默认1分
442 | orderno:订单号(默认系统时间)
443 | outputType:0.返回支付跳转链接 2.返回支付页面(html)
444 | isTest 是否测试 True 测试环境 False 生产环境
445 | '''
446 | def ali_trade04(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,amt = "1", orderno = '',outputType=0,isTest=True)
447 |
448 |
449 | - 银联网页web
450 |
451 | '''
452 | 银联网页web支付
453 | appId:商户应用id
454 | appKey:商户应用秘钥
455 | mhtOrderDetail:订单详情
456 | notifyUrl:商户后台通知URL
457 | frontNotifyUrl :商户前台通知URL
458 | amt:订单金额单位分,默认1分
459 | orderno:订单号(默认系统时间)
460 | outputType:0.返回支付跳转链接 2.返回支付页面(html)
461 | isTest 是否测试 True 测试环境 False 生产环境
462 | '''
463 | def union_trade04(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,amt = "1", orderno = '',outputType=0,isTest=True)
464 |
465 |
466 | - 微信小程序支付
467 |
468 | '''
469 | 微信小程序
470 | appId:商户应用id
471 | appKey:商户应用秘钥
472 | mhtOrderDetail:订单详情
473 | oriMhtOrderAmt:原始金额
474 | discountAmt:优惠金额
475 | notifyUrl:商户后台通知URL
476 | frontNotifyUrl :商户前台通知URL
477 | amt:订单金额单位分,默认1分
478 | orderno:订单号(默认系统时间)
479 | isTest 是否测试 True 测试环境 False 生产环境
480 | '''
481 | def wx_app(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,oriMhtOrderAmt,discountAmt,amt = "1", orderno = '',isTest=True)
482 |
483 |
484 |
485 |
486 | 下单接口字段含义如下:
487 |
488 |
489 |
490 | 字段名称 |
491 | 字段Key |
492 | 备注 |
493 |
494 |
495 | 功能码 |
496 | funcode |
497 | 定值:N001 |
498 |
499 |
500 | 接口版本号 |
501 | version |
502 | 定值:1.0.0 |
503 |
504 |
505 | 商户应用唯一标识 |
506 | appId |
507 | |
508 |
509 |
510 | 商户订单号 |
511 | mhtOrderNo |
512 | |
513 |
514 |
515 | 商户商品名称 |
516 | mhtOrderName |
517 | |
518 |
519 |
520 | 商户交易类型 |
521 | mhtOrderType |
522 | |
523 |
524 |
525 | 商户订单币种类型 |
526 | mhtCurrencyType |
527 | 156人民币 |
528 |
529 |
530 | 商户订单原单金额 |
531 | oriMhtOrderAmt |
532 | 单位(人民币):分 |
533 |
534 |
535 | 商户订单实付金额 |
536 | mhtOrderAmt |
537 | 单位(人民币):分 |
538 |
539 |
540 | 商户订单优惠金额 |
541 | discountAmt |
542 | 单位(人民币):分 |
543 |
544 |
545 | 商户订单超时时间 |
546 | mhtOrderTimeOut |
547 | 60~3600秒,默认3600 |
548 |
549 |
550 | 商户订单开始时间 |
551 | mhtOrderStartTime |
552 | yyyyMMddHHmmss |
553 |
554 |
555 | 支付成功时间 |
556 | payTime |
557 | yyyyMMddHHmmss |
558 |
559 |
560 | 商户字符编码 |
561 | mhtCharset |
562 | UTF-8 |
563 |
564 |
565 | 现在支付流水号 |
566 | nowPayOrderNo |
567 | |
568 |
569 |
570 | 设备类型 |
571 | deviceType |
572 | |
573 |
574 |
575 | 用户所选渠道类型 |
576 | payChannelType |
577 | 12-支付宝 13-微信 27-银联 04-京东 25-手Q |
578 |
579 |
580 | 交易支付状态 |
581 | transStatus |
582 | |
583 |
584 |
585 | 渠道订单号 |
586 | channelOrderNo |
587 | |
588 |
589 |
590 | 付款人账号 |
591 | payConsumerId |
592 | 微信返回sub_openid,支付宝返回buyer_user_id |
593 |
594 |
595 | 商户保留域 |
596 | mhtReserved |
597 | 给商户使用的字段,商户可以对交易进行标记,现在支付将原样返回 |
598 |
599 |
600 | 签名方法 |
601 | signType |
602 | 定值:MD5 |
603 |
604 |
605 | 数据签名 |
606 | signature |
607 | 除signature字段外,所有参数都参与MD5签名 |
608 |
609 |
610 | 银行类型 |
611 | bankType |
612 | 微信渠道返回 |
613 |
614 |
615 | 卡类型 |
616 | cardType |
617 | CREDIT 信用卡 DEBIT 借记卡 |
618 |
619 |
620 |
621 | 2.2 支付结果通知
622 | 通知方式采用httppost方式通知
623 | 字段含义如下:
624 |
625 |
626 |
627 | 字段名称 |
628 | 字段Key |
629 | 备注 |
630 |
631 |
632 | 功能码 |
633 | funcode |
634 | 定值:N001 |
635 |
636 |
637 | 接口版本号 |
638 | version |
639 | 定值:1.0.0 |
640 |
641 |
642 | 商户应用唯一标识 |
643 | appId |
644 | |
645 |
646 |
647 | 商户订单号 |
648 | mhtOrderNo |
649 | |
650 |
651 |
652 | 商户商品名称 |
653 | mhtOrderName |
654 | |
655 |
656 |
657 | 商户交易类型 |
658 | mhtOrderType |
659 | |
660 |
661 |
662 | 商户订单币种类型 |
663 | mhtCurrencyType |
664 | 156人民币 |
665 |
666 |
667 | 商户订单原单金额 |
668 | oriMhtOrderAmt |
669 | 单位(人民币):分 |
670 |
671 |
672 | 商户订单实付金额 |
673 | mhtOrderAmt |
674 | 单位(人民币):分 |
675 |
676 |
677 | 商户订单优惠金额 |
678 | discountAmt |
679 | 单位(人民币):分 |
680 |
681 |
682 | 商户订单超时时间 |
683 | mhtOrderTimeOut |
684 | 60~3600秒,默认3600 |
685 |
686 |
687 | 商户订单开始时间 |
688 | mhtOrderStartTime |
689 | yyyyMMddHHmmss |
690 |
691 |
692 | 支付成功时间 |
693 | payTime |
694 | yyyyMMddHHmmss |
695 |
696 |
697 | 商户字符编码 |
698 | mhtCharset |
699 | UTF-8 |
700 |
701 |
702 | 现在支付流水号 |
703 | nowPayOrderNo |
704 | |
705 |
706 |
707 | 设备类型 |
708 | deviceType |
709 | |
710 |
711 |
712 | 用户所选渠道类型 |
713 | payChannelType |
714 | |
715 |
716 |
717 | 交易支付状态 |
718 | transStatus |
719 | |
720 |
721 |
722 | 渠道订单号 |
723 | channelOrderNo |
724 | |
725 |
726 |
727 | 付款人账号 |
728 | payConsumerId |
729 | 微信返回sub_openid,支付宝返回buyer_user_id |
730 |
731 |
732 | 商户保留域 |
733 | mhtReserved |
734 | 给商户使用的字段,商户可以对交易进行标记,现在支付将原样返回 |
735 |
736 |
737 | 签名方法 |
738 | signType |
739 | 定值:MD5 |
740 |
741 |
742 | 数据签名 |
743 | signature |
744 | 除signature字段外,所有参数都参与MD5签名 |
745 |
746 |
747 | 银行类型 |
748 | bankType |
749 | 微信渠道返回 |
750 |
751 |
752 | 卡类型 |
753 | cardType |
754 | CREDIT 信用卡 DEBIT 借记卡 |
755 |
756 |
757 |
758 | 2.3 订单查询API
759 | 模块:queryOrder.py
760 |
761 |
762 |
763 | - 用户主扫支付订单查询
764 |
765 | '''
766 | 主扫支付订单查询
767 | appId:商户应用id
768 | appKey:商户应用秘钥
769 | orderno:订单号
770 | isTest 是否测试 True 测试环境 False 生产环境
771 | '''
772 | def query08(appId,appKey,orderno,isTest=True)
773 |
774 |
775 |
776 | - 用户被扫支付订单查询
777 |
778 | '''
779 | 主扫支付订单查询
780 | appId:商户应用id
781 | appKey:商户应用秘钥
782 | orderno:订单号
783 | isTest 是否测试 True 测试环境 False 生产环境
784 | '''
785 | def query05(appId,appKey,orderno,isTest=True)
786 |
787 |
788 |
789 | - 公众号支付订单查询
790 |
791 | '''
792 | 公众号订单查询
793 | appId:商户应用id
794 | appKey:商户应用秘钥
795 | orderno:订单号
796 | isTest 是否测试 True 测试环境 False 生产环境
797 | '''
798 | def query0600(appId,appKey,orderno,isTest=True)
799 |
800 |
801 |
802 |
803 | - H5支付订单查询
804 |
805 | '''
806 | H5支付订单查询
807 | appId:商户应用id
808 | appKey:商户应用秘钥
809 | orderno:订单号
810 | isTest 是否测试 True 测试环境 False 生产环境
811 | '''
812 | def query0601(appId,appKey,orderno,isTest=True)
813 |
814 |
815 |
816 |
817 |
818 | - 网页支付订单查询
819 |
820 | '''
821 | 网页支付订单查询
822 | appId:商户应用id
823 | appKey:商户应用秘钥
824 | orderno:订单号
825 | isTest 是否测试 True 测试环境 False 生产环境
826 | '''
827 | def query04(appId,appKey,orderno,isTest=True)
828 |
829 |
830 |
831 | - 小程序支付订单查询
832 |
833 | '''
834 | 小程序支付订单查询
835 | appId:商户应用id
836 | appKey:商户应用秘钥
837 | orderno:订单号
838 | isTest 是否测试 True 测试环境 False 生产环境
839 | '''
840 | def query14(appId,appKey,orderno,isTest=True)
841 |
842 | 订单查询接口字段含义如下:
843 | 接口接入URL:https://pay.ipaynow.cn/ 请求类型:POST
844 |
845 |
846 |
847 | 字段名称 |
848 | 字段Key |
849 | 备注 |
850 |
851 |
852 | 功能码 |
853 | funcode |
854 | 定值:MQ002 |
855 |
856 |
857 | 接口版本号 |
858 | version |
859 | 定值:1.0.0 |
860 |
861 |
862 | 商户应用唯一标识 |
863 | appId |
864 | |
865 |
866 |
867 | 设备类型 |
868 | deviceType |
869 | |
870 |
871 |
872 | 商户订单号 |
873 | mhtOrderNo |
874 | |
875 |
876 |
877 | 商户字符集 |
878 | mhtCharset |
879 | 定值:UTF-8 |
880 |
881 |
882 | 签名方法 |
883 | mhtSignType |
884 | 定值:MD5 |
885 |
886 |
887 | 数据签名 |
888 | mhtSignature |
889 | 除mhtSignature字段外,所有参数都参与MD5签名。 |
890 |
891 |
892 |
893 |
894 | 2.4 退款API
895 | 模块:refund.py
896 |
897 |
898 |
899 | - 退款
900 |
901 | '''
902 | 退款接口
903 | appId:商户应用id
904 | appKey:商户应用秘钥
905 | orderno:原订单号
906 | mhtRefundNo:商户退款单号
907 | amount:商户退款金额
908 | reason:退款原因
909 | isTest 是否测试 True 测试环境 False 生产环境s
910 | '''
911 | def refund(appId,appKey,orderno,mhtRefundNo,amount,reason,isTest=True)
912 |
913 |
914 |
915 | - 退款查询
916 |
917 | '''
918 | 退款查询
919 | appId:商户应用id
920 | appKey:商户应用秘钥
921 | mhtRefundNo:商户退款单号
922 | isTest 是否测试 True 测试环境 False 生产环境
923 | '''
924 | def refundQuery(appId,appKey,mhtRefundNo,isTest=True)
925 |
926 |
927 |
928 | - 撤销
929 |
930 | '''
931 | 撤销接口
932 | appId:商户应用id
933 | appKey:商户应用秘钥
934 | orderno:原订单号
935 | mhtRefundNo:商户退款单号
936 | reason:撤销原因
937 | isTest 是否测试 True 测试环境 False 生产环境
938 | '''
939 | def backOrder(appId,appKey,orderno,mhtRefundNo,reason,isTest=True)
940 |
941 |
942 |
943 | - 撤销查询
944 |
945 | '''
946 | 撤销查询接口
947 | appId:商户应用id
948 | appKey:商户应用秘钥
949 | mhtRefundNo:商户退款单号
950 | isTest 是否测试 True 测试环境 False 生产环境
951 | '''
952 | def backOrderQuery(appId,appKey,mhtRefundNo,isTest=True)
--------------------------------------------------------------------------------
/example/backOrderQueryTest.py:
--------------------------------------------------------------------------------
1 | from ipaynowPythonSdk.ipaynow.refund import backOrderQuery
2 |
3 | # print(backOrderQuery("xxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxxxx","0rQi6rtXKM1dH"))
--------------------------------------------------------------------------------
/example/backOrderTest.py:
--------------------------------------------------------------------------------
1 | from ipaynowPythonSdk.ipaynow.refund import backOrder
2 |
3 | # print(backOrder("xxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxxxxx","0rQi6rtXKM1dH","20171117","测试退款"))
--------------------------------------------------------------------------------
/example/queryOrderTest.py:
--------------------------------------------------------------------------------
1 | from ipaynowPythonSdk.ipaynow.queryOrder import queryOrder
2 |
3 | # print (queryOrder("xxxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxx","eY85WUOEoSP1X"))
4 |
5 |
--------------------------------------------------------------------------------
/example/refundTest.py:
--------------------------------------------------------------------------------
1 | from ipaynowPythonSdk.ipaynow.refund import refund
2 |
3 | print(refund("xxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxxxxx","xxxxx","20171117","1","测试退款"))
--------------------------------------------------------------------------------
/example/tradeTest.py:
--------------------------------------------------------------------------------
1 | from ipaynowPythonSdk.ipaynow.trade import ali_trade08
2 |
3 | print (ali_trade08("xxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxx","详情","www.baidu.com",isTest=False))
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 | from ipaynowPythonSdk.ipaynow.version import VERSION
4 | from ipaynowPythonSdk.ipaynow.interface import (
5 | query,
6 | notify,
7 | # front_notify,
8 | parseTrade,
9 | parseQuery,
10 | parseNotify,
11 | parseFrontNotify
12 | )
13 |
14 | from ipaynowPythonSdk.ipaynow.error import (
15 | APIError,
16 | APIInputError
17 | )
18 |
19 | from ipaynowPythonSdk.ipaynow.utils import trans2unicode
20 |
21 | __all__ = ['trade','query','notify','front_notify','parseTrade','parseQuery','parseNotify','parseFrontNotify','APIError','APIInputError','trans2unicode']
22 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/error.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 |
4 | import getopt, sys
5 |
6 | class IpaynowError(Exception):
7 | def __init__(self, message=None):
8 | super(IpaynowError, self).__init__(message)
9 | self._message = message
10 | def __unicode__(self):
11 | return self._message
12 |
13 | if sys.version_info > (3, 0):
14 | __str__ = lambda self: self.__unicode__()
15 | else:
16 | __str__ = lambda self: unicode(self).encode('utf-8')
17 |
18 | class APIError(IpaynowError):
19 | pass
20 |
21 | class APIInputError(IpaynowError):
22 | pass
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/interface.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 | from ipaynowPythonSdk.ipaynow.packMsg import PackMsgSend
4 | from ipaynowPythonSdk.ipaynow.paramlist import WP001_PostList, WP001_RespList
5 | from ipaynowPythonSdk.ipaynow.paramlist import MQ001_PostList, MQ001_RespList
6 | from ipaynowPythonSdk.ipaynow.paramlist import N001_QueryList, N001_RespList
7 | from ipaynowPythonSdk.ipaynow.paramlist import N002_NotifyList
8 | from ipaynowPythonSdk.ipaynow.unpackMsg import UnpackMsgRecv
9 | from ipaynowPythonSdk.ipaynow.paramlist import MQ001_PostList, R001_PostList, Q001_PostList, R002_PostList, \
10 | Q002_PostList
11 |
12 |
13 | #下单及查询
14 | proTradeUrl = "https://pay.ipaynow.cn";
15 | testTradeUrl = "https://dby.ipaynow.cn/api/payment";
16 |
17 | #退款撤销
18 | proRefundUrl = "https://pay.ipaynow.cn/refund/refundOrder";
19 | testRefundUrl = "https://dby.ipaynow.cn/refund_access/refundOrder";
20 |
21 | #退款查询
22 | proRefundQueryUrl = "https://pay.ipaynow.cn/refund/refundQuery";
23 | testRefundQueryUrl = "https://dby.ipaynow.cn/refund_access/refundQuery";
24 |
25 |
26 | def trade(appKey,payparam = {}):
27 |
28 | pms = PackMsgSend(appKey,payparam,WP001_PostList)
29 | return pms.getResultString()
30 |
31 | def query(appKey,queryparam = {}):
32 |
33 | pms = PackMsgSend(appKey,queryparam,MQ001_PostList)
34 | return pms.getResultString()
35 |
36 | def refund(appKey,queryparam = {}):
37 | pms = PackMsgSend(appKey,queryparam,R001_PostList)
38 | return pms.getResultString()
39 |
40 | def refundQuery(appKey,queryparam = {}):
41 | pms = PackMsgSend(appKey,queryparam,Q001_PostList)
42 | return pms.getResultString()
43 |
44 | def backOrder(appKey,queryparam = {}):
45 | pms = PackMsgSend(appKey,queryparam,R002_PostList)
46 | return pms.getResultString()
47 |
48 | def backOrderQuery(appKey,queryparam = {}):
49 | pms = PackMsgSend(appKey,queryparam,Q002_PostList)
50 | return pms.getResultString()
51 |
52 | def notify(frontNotifyParam = 'Y'):
53 | stringRtn = "{'success':'%s'}" %frontNotifyParam
54 | return stringRtn
55 |
56 | def parseTrade(instr = ""):
57 | upm = UnpackMsgRecv(instr,WP001_RespList)
58 | recvDict = upm.getResultDict()
59 | isVerified = upm.verifyResponse()
60 | return (recvDict,isVerified)
61 |
62 | def parseQuery(instr = ""):
63 | # instrunicode = trans2unicode(instr)
64 | upm = UnpackMsgRecv(instr,MQ001_RespList)
65 | recvDict = upm.getResultDict()
66 | isVerified = upm.verifyResponse()
67 | return (recvDict,isVerified)
68 |
69 | def parseNotify(instr = ""):
70 | upm = UnpackMsgRecv(instr,N001_QueryList)
71 | recvDict = upm.getResultDict()
72 | isVerified = upm.verifyResponse()
73 | return (recvDict,isVerified)
74 |
75 | def parseFrontNotify(instr = ""):
76 | upm = UnpackMsgRecv(instr,N002_NotifyList)
77 | recvDict = upm.getResultDict()
78 | isVerified = upm.verifyResponse()
79 | return (recvDict,isVerified)
80 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/jsonParseFaced.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ipaynowORG/ipaynow_pay_python/5fc9112e39de1ff86765ee700e63b1a7cf1482c5/ipaynowPythonSdk/ipaynow/jsonParseFaced.py
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/md5Faced.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
2 |
3 | from ipaynowPythonSdk.ipaynow import utils
4 |
5 | __all__ = ['md5calc']
6 |
7 | try:
8 | import hashlib
9 | except ImportError:
10 | hashlib = None
11 |
12 | if not hashlib:
13 | raise ImportError(
14 | "ipaynow sdk can't import hashlib.please check if it "
15 | )
16 |
17 |
18 | def md5calc(md5source):
19 | try:
20 | m = hashlib.md5()
21 | m.update(md5source)
22 | return m.hexdigest()
23 | except Exception as e:
24 | print(e.args)
25 | return ""
26 |
27 | if __name__ == "__main__":
28 | strout = "MD5 test string :"
29 | strtest = ""
30 | strout += strtest
31 | strmd5 = md5calc(strtest.encode('utf-8'))
32 | strout += "\nMD5 result string :" + strmd5
33 | print(strout)
34 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/packMsg.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 |
4 | from ipaynowPythonSdk.ipaynow.paramlist import WP001_PostList
5 | from ipaynowPythonSdk.ipaynow.error import APIInputError
6 | from ipaynowPythonSdk.ipaynow.md5Faced import md5calc
7 |
8 | try:
9 | from urllib import urlencode
10 | except ImportError:
11 | from urllib.parse import urlencode
12 | import getopt, sys
13 |
14 |
15 | def usage():
16 | print('''
17 | NAME
18 | pack send message.
19 | Usage
20 | python packMsg.py [options]
21 | ''')
22 |
23 |
24 | class PackMsgSend:
25 | __srcDict = {}
26 | __tarDict = {}
27 | __tarDictJoinMd5 = {}
28 | __tarListJoinMd5 = []
29 | __filterRule = []
30 | __fromStrMd5 = ""
31 | # __md5Key = ""
32 | __appKey = ""
33 | __md5Result = ""
34 |
35 | def __init__(self, appKey, sourcedict={}, filterrule=[]):
36 | self.__appKey = appKey
37 | self.__srcDict = sourcedict
38 | self.__filterRule = filterrule
39 |
40 | def __inputFilter(self):
41 | '''
42 | from __srcDict to __tarDict
43 | use paramlist to filter the input dictionary.
44 | '''
45 | for singleParam in self.__filterRule:
46 | filedName = singleParam['name']
47 | # judeg if the filedName exist in source dictionary.
48 | if filedName in self.__srcDict: # exist
49 | # the filedName is exist in sourcedict.
50 | # then judge if the length is right.
51 | srcContent = self.__srcDict[filedName]
52 | if (len(str(srcContent)) > singleParam['len']):
53 | errmsg = '''Your input parameter [{}] is too long. Max length is [{}].'''.format(filedName,
54 | singleParam['len'])
55 | raise APIInputError(errmsg)
56 | if (len(str(srcContent)) == 0):
57 | continue
58 | self.__tarDict[filedName] = srcContent
59 | # if the info needs md5 calc .
60 | if (singleParam['md5'] == 'Y'):
61 | self.__tarDictJoinMd5[filedName] = srcContent
62 | else: # no exist
63 | # judge if the parameter is mandatory
64 | if singleParam['mandatory'] == 'Y': # this parameter is mandatory
65 | if filedName == 'mhtSignature':
66 | continue
67 | errmsg = '''You should input parameter [{}].this parameter indicts [{}].'''.format(filedName,
68 | singleParam[
69 | 'desp'])
70 | raise APIInputError(errmsg)
71 | else:
72 | continue
73 | self.__sortDict()
74 |
75 | def __sortDict(self):
76 | sortedListJoinmd5 = sorted(self.__tarDictJoinMd5.items(), key=lambda e: e[0], reverse=False)
77 | self.__tarListJoinMd5 = sortedListJoinmd5
78 |
79 | def __createFromStr(self):
80 | fromstrmd5 = ""
81 | for formContentMd5 in self.__tarListJoinMd5:
82 | if formContentMd5[1] == '' or formContentMd5[1] == None:
83 | continue
84 | fromstrmd5 += str(formContentMd5[0]) + "=" + str(formContentMd5[1]) + "&"
85 | self.__fromStrMd5 = fromstrmd5
86 |
87 | def __calcMd5(self):
88 | # remove string that don't join md5 calc
89 | sourceString = self.__fromStrMd5
90 | securityKeyMd5 = md5calc(self.__appKey.encode('utf-8'))
91 | sourceString += securityKeyMd5
92 | # print("待签名字符串:{}".format(sourceString))
93 | md5Result = md5calc(sourceString.encode('utf_8'))
94 | self.__tarDict['mhtSignature'] = md5Result
95 | self.__md5Result = md5Result
96 |
97 | def getResultString(self):
98 | self.__inputFilter()
99 | self.__createFromStr()
100 | self.__calcMd5()
101 | resultStr = urlencode(self.__tarDict)
102 | return resultStr
103 |
104 | def test(self):
105 | # print("__fromstr :",self.__fromStr)
106 | # print("__fromstrmd5 :",self.__fromStrMd5)
107 | # print("__tarDict :",self.__tarDict)
108 | # print("__tarDictJoinMd5 :",self.__tarDictJoinMd5)
109 | pass
110 |
111 |
112 | if __name__ == '__main__':
113 | try:
114 | opts, args = getopt.getopt(sys.argv[1:], "hf:", ["help", "file="])
115 | except getopt.GetoptError as err:
116 | # print help information and exit:
117 | print(str(err)) # will print something like "option -a not recognized"
118 | usage()
119 | sys.exit(2)
120 |
121 | file = ""
122 |
123 | for o, a in opts:
124 | if o in ("-h", "--help"):
125 | usage()
126 | sys.exit()
127 | elif o in ("-f", "--file"):
128 | file = a
129 | else:
130 | assert False, "unhandled option"
131 | paypara = {
132 | 'funcode': 'WP001',
133 | 'version': '1.0.0',
134 | 'appId': '150753082825470',
135 | 'mhtOrderType': '01',
136 | 'mhtCurrencyType': '156',
137 | 'mhtOrderDetail': 'ipaynowPythonSDKTestOrder',
138 | 'mhtOrderTimeOut': 3600,
139 | 'notifyUrl': 'http://posp.ipaynow.cn:10808/cpgatetest/notify',
140 | 'mhtCharset': 'UTF-8',
141 | 'deviceType': '05',
142 | 'payChannelType': '13',
143 | 'channelAuthCode': '134954669523328956',
144 | 'mhtReserved': '',
145 | 'consumerId': '',
146 | 'mhtSignType': 'MD5'
147 | }
148 | import time
149 |
150 | timestr = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
151 | paypara['mhtOrderStartTime'] = '20171027101225'
152 | try:
153 | pms = PackMsgSend("8jTST7ywIBY0QQ3RlcxWEl08Xj9gaYyQ", paypara, WP001_PostList)
154 | resultStr = pms.getResultString()
155 | print(resultStr)
156 | except APIInputError as e:
157 | print(e)
158 |
159 | print("============")
160 | # print(quote_plus(resultStr,safe='=&'))
161 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/paramlist.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 |
4 | # define interface parameter attributes and max len
5 |
6 | # key name 'name' indicates parameter name
7 | # key name 'must' indicates parameter
8 | # WP001-无插件聚合支付
9 | WP001_PostList = [
10 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
11 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
12 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
13 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
14 | {'name': 'mhtOrderName', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户商品名称"},
15 | {'name': 'mhtOrderType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户交易类型"},
16 | {'name': 'mhtCurrencyType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 3, 'desp': "商户订单币种类型"},
17 | {'name': 'mhtOrderAmt', 'mandatory': 'Y', 'md5': 'Y', 'type': 'num', 'len': 22, 'desp': "商户订单交易金额"},
18 | {'name': 'mhtOrderDetail', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 200, 'desp': "商户订单详情"},
19 | {'name': 'mhtOrderTimeOut', 'mandatory': 'N', 'md5': 'Y', 'type': 'num', 'len': 4, 'desp': "商户订单超时时间"},
20 | {'name': 'mhtOrderStartTime', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 14, 'desp': "商户订单开始时间"},
21 | {'name': 'notifyUrl', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 200, 'desp': "商户后台通知URL"},
22 | {'name': 'frontNotifyUrl', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 200, 'desp': "商户前台通知URL"},
23 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 16, 'desp': "商户字符编码-UTF8"},
24 | {'name': 'deviceType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "设备类型"},
25 | {'name': 'payChannelType', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "用户所选渠道类型"},
26 | {'name': 'channelAuthCode', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 20, 'desp': "渠道编号"},
27 | {'name': 'mhtReserved', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 100, 'desp': "商户保留域"},
28 | {'name': 'consumerId', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "消费者ID"},
29 | {'name': 'outputType', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "输出格式"},
30 | {'name': 'mhtSubAppId', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "公众号appId"},
31 | {'name': 'mhtSignType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 3, 'desp': "商户签名方法-MD5"},
32 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 64, 'desp': "商户数据签名"}
33 |
34 | ]
35 | # 接口接入URL:https://api.ipaynow.cn 请求类型:POST
36 |
37 | # WP001-无插件聚合支付 Response
38 | # 支付交易同步返回
39 | WP001_RespList = [
40 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 4, 'desp': "功能码"},
41 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
42 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
43 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
44 | {'name': 'responseTime', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 40, 'desp': "响应时间"},
45 | {'name': 'responseCode', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 4, 'desp': "响应码"},
46 | {'name': 'responseMsg', 'mandatory': 'N', 'md5': 'N', 'type': 'str', 'len': 100, 'desp': "响应信息"},
47 | {'name': 'nowPayOrderNo', 'mandatory': 'N', 'md5': 'N', 'type': 'str', 'len': 40, 'desp': "现在支付订单号(TN)"}
48 | ]
49 |
50 | # MQ002-商户支付订单查询
51 | # 接口接入URL:https://api.ipaynow.cn 请求类型:POST 由商户发起
52 | MQ001_PostList = [
53 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
54 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
55 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
56 | {'name': 'deviceType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "设备类型"},
57 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
58 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符集"},
59 | {'name': 'mhtSignType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "签名方法"},
60 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "数据签名"}
61 | ]
62 |
63 | # R001-退款接口
64 | # 接口接入URL:https://pay.ipaynow.cn/refund/refundOrder 请求类型:POST
65 | R001_PostList = [
66 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
67 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
68 | {'name': 'mhtRefundNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户退款单号"},
69 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "原商户订单号"},
70 | {'name': 'amount', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 10, 'desp': "商户退款金额"},
71 | {'name': 'reason', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 256, 'desp': "退款原因"},
72 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符集"},
73 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
74 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "数据签名"}
75 | ]
76 |
77 |
78 | # Q001-退款查询接口
79 | # 接口接入URL:https://pay.ipaynow.cn/refund/refundQuery
80 | Q001_PostList = [
81 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
82 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
83 | {'name': 'mhtRefundNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户退款单号"},
84 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符集"},
85 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
86 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "数据签名"}
87 | ]
88 |
89 |
90 | # R002-撤销接口
91 | # 接口接入URL:https://pay.ipaynow.cn/refund/refundOrder 请求类型:POST
92 | R002_PostList = [
93 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
94 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
95 | {'name': 'mhtRefundNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户退款单号"},
96 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "原商户订单号"},
97 | {'name': 'reason', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 256, 'desp': "退款原因"},
98 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符集"},
99 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
100 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 64, 'desp': "数据签名"}
101 | ]
102 |
103 |
104 | # Q001-退款查询接口
105 | # 接口接入URL:https://pay.ipaynow.cn/refund/refundQuery
106 | Q002_PostList = [
107 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "功能码"},
108 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
109 | {'name': 'mhtRefundNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户撤销单号"},
110 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符集"},
111 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
112 | {'name': 'mhtSignature', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "数据签名"}
113 | ]
114 |
115 | # MQ001-商户支付订单查询 Response
116 | # 支付交易同步返回
117 | MQ001_RespList = [
118 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
119 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
120 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
121 | {'name': 'mhtOrderName', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户商品名称"},
122 | {'name': 'mhtOrderType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "订单交易类型"},
123 | {'name': 'mhtCurrencyType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 3, 'desp': "订单币种类型"},
124 | {'name': 'mhtOrderAmt', 'mandatory': 'Y', 'md5': 'Y', 'type': 'num', 'len': 22, 'desp': "订单交易金额"},
125 | {'name': 'mhtOrderTimeOut', 'mandatory': 'N', 'md5': 'Y', 'type': 'num', 'len': 4, 'desp': "订单超时时间"},
126 | {'name': 'mhtOrderStartTime', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 14, 'desp': "订单开始时间"},
127 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "交易字符编码"},
128 | {'name': 'deviceType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "设备类型"},
129 | {'name': 'payChannelType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "用户所选渠道类型"},
130 | {'name': 'fee', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 22, 'desp': "交易手续费"},
131 | {'name': 'settleAmt', 'mandatory': 'N', 'md5': 'Y', 'type': 'num', 'len': 22, 'desp': "商户结算金额"},
132 | {'name': 'transStatus', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "交易状态"},
133 | {'name': 'responseTime', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 14, 'desp': "响应时间"},
134 | {'name': 'responseCode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "响应码"},
135 | {'name': 'responseMsg', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 100, 'desp': "响应信息"},
136 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
137 | {'name': 'signature', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 64, 'desp': "数据签名"}
138 | ]
139 |
140 | # N001-商户服务器端支付结果通知
141 | # 现在支付的聚合支付服务端异步发起: --通讯方式:HTTP POST 方式--
142 | N001_QueryList = [
143 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "功能码"},
144 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
145 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
146 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
147 | {'name': 'mhtOrderName', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户商品名称"},
148 | {'name': 'mhtOrderType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "商户交易类型"},
149 | {'name': 'mhtCurrencyType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 3, 'desp': "商户订单币种类型"},
150 | {'name': 'mhtOrderAmt', 'mandatory': 'Y', 'md5': 'Y', 'type': 'num', 'len': 22, 'desp': "商户订单交易金额"},
151 | {'name': 'mhtOrderTimeOut', 'mandatory': 'N', 'md5': 'Y', 'type': 'num', 'len': 4, 'desp': "商户订单超时时间"},
152 | {'name': 'mhtOrderStartTime', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 14, 'desp': "商户订单开始时间"},
153 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符编码"},
154 | {'name': 'deviceType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "设备类型"},
155 | {'name': 'payChannelType', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 2, 'desp': "用户所选渠道类型"},
156 | {'name': 'nowPayOrderNo', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "现在支付账号"},
157 | {'name': 'tradeStatus', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "交易支付状态"},
158 | {'name': 'mhtReserved', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 100, 'desp': "商户保留域"},
159 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 6, 'desp': "签名方法"},
160 | {'name': 'signature', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 64, 'desp': "数据签名"},
161 | {'name': 'channelOrderNo', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 100, 'desp': "渠道订单号"}
162 | ]
163 |
164 | # N001-商户服务器端支付结果通知 Resp
165 | N001_RespList = [
166 | {'name': 'success', 'mandatory': 'Y', 'md5': 'N', 'type': 'str', 'len': 1, 'desp': "是否成功"}
167 | ]
168 |
169 | # N002-商户前端支付结果通知
170 | N002_NotifyList = [
171 | {'name': 'funcode', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "功能码"},
172 | {'name': 'version', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 5, 'desp': "版本1.0.0"},
173 | {'name': 'appId', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户应用唯一标识"},
174 | {'name': 'mhtOrderNo', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 40, 'desp': "商户订单号"},
175 | {'name': 'mhtCharset', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "商户字符编码"},
176 | {'name': 'tradeStatus', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 4, 'desp': "交易支付状态"},
177 | {'name': 'mhtReserved', 'mandatory': 'N', 'md5': 'Y', 'type': 'str', 'len': 100, 'desp': "商户保留域"},
178 | {'name': 'signType', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 6, 'desp': "签名方法"},
179 | {'name': 'signature', 'mandatory': 'Y', 'md5': 'Y', 'type': 'str', 'len': 64, 'desp': "数据签名"},
180 | ]
181 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/queryOrder.py:
--------------------------------------------------------------------------------
1 | import random
2 | import string
3 | import urllib
4 | from datetime import time
5 |
6 | from pip._vendor import requests
7 |
8 | from ipaynowPythonSdk.ipaynow import interface
9 | from ipaynowPythonSdk.ipaynow.interface import proTradeUrl, testTradeUrl
10 |
11 | '''
12 | 主扫支付订单查询
13 | appId:商户应用id
14 | appKey:商户应用秘钥
15 | orderno:订单号
16 | isTest 是否测试 True 测试环境 False 生产环境
17 | '''
18 | def query08(appId,appKey,orderno,isTest=True):
19 | return queryOrder(appId,appKey,"08",orderno,isTest)
20 |
21 | '''
22 | 被扫支付订单查询
23 | appId:商户应用id
24 | appKey:商户应用秘钥
25 | orderno:订单号
26 | isTest 是否测试 True 测试环境 False 生产环境
27 | '''
28 | def query05(appId,appKey,orderno,isTest=True):
29 | return queryOrder(appId,appKey,"05",orderno,isTest)
30 |
31 |
32 | '''
33 | 网页支付订单查询
34 | appId:商户应用id
35 | appKey:商户应用秘钥
36 | orderno:订单号
37 | isTest 是否测试 True 测试环境 False 生产环境
38 | '''
39 | def query04(appId,appKey,orderno,isTest=True):
40 | return queryOrder(appId,appKey,"04",orderno,isTest)
41 |
42 | '''
43 | 公众号支付订单查询
44 | appId:商户应用id
45 | appKey:商户应用秘钥
46 | orderno:订单号
47 | isTest 是否测试 True 测试环境 False 生产环境
48 | '''
49 | def query0600(appId,appKey,orderno,isTest=True):
50 | return queryOrder(appId,appKey,"0600",orderno,isTest)
51 |
52 |
53 | '''
54 | H5支付订单查询
55 | appId:商户应用id
56 | appKey:商户应用秘钥
57 | orderno:订单号
58 | isTest 是否测试 True 测试环境 False 生产环境
59 | '''
60 | def query0601(appId,appKey,orderno,isTest=True):
61 | return queryOrder(appId,appKey,"0601",orderno,isTest)
62 |
63 | '''
64 | 小程序支付订单查询
65 | appId:商户应用id
66 | appKey:商户应用秘钥
67 | orderno:订单号
68 | isTest 是否测试 True 测试环境 False 生产环境
69 | '''
70 | def query14(appId,appKey,orderno,isTest=True):
71 | return queryOrder(appId,appKey,"14",orderno,isTest)
72 |
73 |
74 | def queryOrder(appId,appKey,deviceType, orderno,isTest):
75 | paypara = {
76 | 'funcode':'MQ002',
77 | 'version': '1.0.0',
78 | 'appId':appId,
79 | 'mhtCharset': 'UTF-8',
80 | 'deviceType': deviceType,
81 | 'mhtSignType':'MD5',
82 | 'mhtOrderNo':orderno
83 |
84 | }
85 | try:
86 | tradestr = interface.query(appKey,paypara)
87 | except interface.APIInputError as ipse:
88 | print(ipse)
89 | except Exception as e:
90 | print(e)
91 | print(e.with_traceback)
92 | if isTest:
93 | url = testTradeUrl
94 | else:
95 | url = proTradeUrl
96 | resp = requests.post(url,tradestr)
97 | return urllib.parse.unquote(resp.text)
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/refund.py:
--------------------------------------------------------------------------------
1 | import urllib
2 |
3 | from pip._vendor import requests
4 |
5 | from ipaynowPythonSdk.ipaynow import interface
6 |
7 |
8 | import urllib
9 |
10 | from pip._vendor import requests
11 |
12 | from ipaynowPythonSdk.ipaynow import interface
13 | from ipaynowPythonSdk.ipaynow.interface import testRefundUrl, proRefundUrl, testRefundQueryUrl, proRefundQueryUrl
14 |
15 | '''
16 | 撤销查询接口
17 | appId:商户应用id
18 | appKey:商户应用秘钥
19 | mhtRefundNo:商户退款单号
20 | isTest 是否测试 True 测试环境 False 生产环境
21 | '''
22 | def backOrderQuery(appId,appKey,mhtRefundNo,isTest=True):
23 | paypara = {
24 | 'funcode':'Q002',
25 | 'appId':appId,
26 | 'mhtCharset': 'UTF-8',
27 | 'signType':'MD5',
28 | 'mhtRefundNo':mhtRefundNo
29 | }
30 | try:
31 | refundstr = interface.backOrderQuery(appKey,paypara)
32 | except interface.APIInputError as ipse:
33 | print(ipse)
34 | except Exception as e:
35 | print(e)
36 | print(e.with_traceback)
37 | if isTest:
38 | url = testRefundUrl
39 | else:
40 | url = proRefundUrl
41 | resp = requests.post(url,refundstr)
42 | return urllib.parse.unquote(resp.text)
43 |
44 | '''
45 | 撤销接口
46 | appId:商户应用id
47 | appKey:商户应用秘钥
48 | orderno:原订单号
49 | mhtRefundNo:商户退款单号
50 | reason:撤销原因
51 | isTest 是否测试 True 测试环境 False 生产环境
52 | '''
53 | def backOrder(appId,appKey,orderno,mhtRefundNo,reason,isTest=True):
54 | paypara = {
55 | 'funcode':'R002',
56 | 'appId':appId,
57 | 'mhtCharset': 'UTF-8',
58 | 'reason': reason,
59 | 'signType':'MD5',
60 | 'mhtOrderNo':orderno,
61 | 'mhtRefundNo':mhtRefundNo
62 | }
63 | try:
64 | refundstr = interface.backOrder(appKey,paypara)
65 | except interface.APIInputError as ipse:
66 | print(ipse)
67 | except Exception as e:
68 | print(e)
69 | print(e.with_traceback)
70 | if isTest:
71 | url = testRefundUrl
72 | else:
73 | url = proRefundUrl
74 | print(refundstr)
75 | resp = requests.post(url,refundstr)
76 | return urllib.parse.unquote(resp.text)
77 |
78 |
79 | '''
80 | 退款查询
81 | appId:商户应用id
82 | appKey:商户应用秘钥
83 | mhtRefundNo:商户退款单号
84 | isTest 是否测试 True 测试环境 False 生产环境
85 | '''
86 | def refundQuery(appId,appKey,mhtRefundNo,isTest=True):
87 | paypara = {
88 | 'funcode':'Q001',
89 | 'appId':appId,
90 | 'mhtCharset': 'UTF-8',
91 | 'signType':'MD5',
92 | 'mhtRefundNo':mhtRefundNo
93 | }
94 | try:
95 | refundstr = interface.refundQuery(appKey,paypara)
96 | except interface.APIInputError as ipse:
97 | print(ipse)
98 | except Exception as e:
99 | print(e)
100 | print(e.with_traceback)
101 | if isTest:
102 | url = testRefundQueryUrl
103 | else:
104 | url = proRefundQueryUrl
105 | resp = requests.post(url,refundstr)
106 | return urllib.parse.unquote(resp.text)
107 |
108 |
109 | '''
110 | 退款接口
111 | appId:商户应用id
112 | appKey:商户应用秘钥
113 | orderno:原订单号
114 | mhtRefundNo:商户退款单号
115 | amount:商户退款金额
116 | reason:退款原因
117 | isTest 是否测试 True 测试环境 False 生产环境
118 | '''
119 | def refund(appId,appKey,orderno,mhtRefundNo,amount,reason,isTest = True):
120 | paypara = {
121 | 'funcode':'R001',
122 | 'appId':appId,
123 | 'mhtCharset': 'UTF-8',
124 | 'amount': amount,
125 | 'reason': reason,
126 | 'signType':'MD5',
127 | 'mhtOrderNo':orderno,
128 | 'mhtRefundNo':mhtRefundNo
129 | }
130 | try:
131 | refundstr = interface.refund(appKey,paypara)
132 | except interface.APIInputError as ipse:
133 | print(ipse)
134 | except Exception as e:
135 | print(e)
136 | print(e.with_traceback)
137 | if isTest:
138 | url = testRefundUrl
139 | else:
140 | url = proRefundUrl
141 | resp = requests.post(url,refundstr)
142 | return urllib.parse.unquote(resp.text)
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/trade.py:
--------------------------------------------------------------------------------
1 | import random
2 | import string
3 | import time
4 | import urllib
5 |
6 | from ipaynowPythonSdk.ipaynow import interface
7 | from pip._vendor import requests
8 |
9 | from ipaynowPythonSdk.ipaynow.interface import testTradeUrl, proTradeUrl
10 |
11 | '''
12 | 微信公众号支付
13 | appId:商户应用id
14 | appKey:商户应用秘钥
15 | mhtOrderDetail:订单详情
16 | notifyUrl:商户后台通知URL
17 | frontNotifyUrl :商户前台通知URL
18 | isTest 是否测试 True 测试环境 False 生产环境
19 | amt:订单金额单位分,默认1分
20 | orderno:订单号(默认系统时间)
21 | outputType ; 0-公众号0模式
22 | '''
23 | def wx_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
24 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="13",deviceType="0600",amt = amt, orderno = orderno,outputType=outputType)
25 |
26 | '''
27 | 支付宝公众号支付
28 | appId:商户应用id
29 | appKey:商户应用秘钥
30 | mhtOrderDetail:订单详情
31 | notifyUrl:商户后台通知URL
32 | frontNotifyUrl :商户前台通知URL
33 | isTest 是否测试 True 测试环境 False 生产环境
34 | amt:订单金额单位分,默认1分
35 | orderno:订单号(默认系统时间)
36 | outputType ; 0-公众号0模式
37 | '''
38 | def ali_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
39 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,frontNotifyUrl=frontNotifyUrl,payChannelType="12",deviceType="0600",amt = amt, orderno = orderno,outputType=outputType)
40 |
41 |
42 | '''
43 | 手Q公众号支付
44 | appId:商户应用id
45 | appKey:商户应用秘钥
46 | mhtOrderDetail:订单详情
47 | notifyUrl:商户后台通知URL
48 | frontNotifyUrl :商户前台通知URL
49 | isTest 是否测试 True 测试环境 False 生产环境
50 | amt:订单金额单位分,默认1分
51 | orderno:订单号(默认系统时间)
52 | outputType ; 0-公众号0模式
53 | '''
54 | def handq_trade0600(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
55 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="25",deviceType="0600",amt = amt, orderno = orderno,outputType=outputType)
56 |
57 | '''
58 | 微信主扫支付
59 | appId:商户应用id
60 | appKey:商户应用秘钥
61 | mhtOrderDetail:订单详情
62 | notifyUrl:商户后台通知URL
63 | isTest 是否测试 True 测试环境 False 生产环境
64 | amt:订单金额单位分,默认1分
65 | orderno:订单号(默认系统时间)
66 | outputType ; 0 返回二维码串 1 返回支付链接
67 | '''
68 | def wx_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True):
69 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="13",deviceType="08",amt = amt, orderno = orderno,outputType=outputType)
70 |
71 |
72 | '''
73 | 支付宝主扫支付
74 | appId:商户应用id
75 | appKey:商户应用秘钥
76 | mhtOrderDetail:订单详情
77 | notifyUrl:商户后台通知URL
78 | amt:订单金额单位分,默认1分
79 | orderno:订单号(默认系统时间)
80 | outputType ; 0 返回二维码串 1 返回支付链接
81 | isTest 是否测试 True 测试环境 False 生产环境
82 | '''
83 | def ali_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType="0",amt = "1", orderno = '',isTest=True):
84 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="12",deviceType="08",amt = amt, orderno = orderno,outputType=outputType)
85 |
86 | '''
87 | 手Q主扫支付
88 | appId:商户应用id
89 | appKey:商户应用秘钥
90 | mhtOrderDetail:订单详情
91 | notifyUrl:商户后台通知URL
92 | isTest 是否测试 True 测试环境 False 生产环境
93 | amt:订单金额单位分,默认1分
94 | orderno:订单号(默认系统时间)
95 | outputType ; 0 返回二维码串 1 返回支付链接
96 | '''
97 | def handq_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True):
98 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="25",deviceType="08",amt = amt, orderno = orderno,outputType=outputType)
99 |
100 | '''
101 | 京东主扫支付
102 | appId:商户应用id
103 | appKey:商户应用秘钥
104 | mhtOrderDetail:订单详情
105 | notifyUrl:商户后台通知URL
106 | isTest 是否测试 True 测试环境 False 生产环境
107 | amt:订单金额单位分,默认1分
108 | orderno:订单号(默认系统时间)
109 | outputType ; 0 返回二维码串 1 返回支付链接
110 | '''
111 | def jd_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True):
112 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="04",deviceType="08",amt = amt, orderno = orderno,outputType=outputType)
113 |
114 |
115 | '''
116 | 银联主扫支付
117 | appId:商户应用id
118 | appKey:商户应用秘钥
119 | mhtOrderDetail:订单详情
120 | notifyUrl:商户后台通知URL
121 | isTest 是否测试 True 测试环境 False 生产环境
122 | amt:订单金额单位分,默认1分
123 | orderno:订单号(默认系统时间)
124 | outputType ; 0 返回二维码串 1 返回支付链接
125 | '''
126 | def union_trade08(appId,appKey,ordername,mhtOrderDetail,notifyUrl,outputType,amt = "1", orderno = '',isTest=True):
127 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="27",deviceType="08",amt = amt, orderno = orderno,outputType=outputType)
128 |
129 | '''
130 | 微信被扫支付
131 | appId:商户应用id
132 | appKey:商户应用秘钥
133 | mhtOrderDetail:订单详情
134 | notifyUrl:商户后台通知URL
135 | isTest 是否测试 True 测试环境 False 生产环境
136 | amt:订单金额单位分,默认1分
137 | orderno:订单号(默认系统时间)
138 | channelAuthCode ; 支付授权码
139 | '''
140 | def wx_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
141 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="13",deviceType="05",amt = amt, orderno = orderno,channelAuthCode=channelAuthCode)
142 |
143 |
144 | '''
145 | 支付宝被扫支付
146 | appId:商户应用id
147 | appKey:商户应用秘钥
148 | mhtOrderDetail:订单详情
149 | notifyUrl:商户后台通知URL
150 | isTest 是否测试 True 测试环境 False 生产环境
151 | amt:订单金额单位分,默认1分
152 | orderno:订单号(默认系统时间)
153 | channelAuthCode ; 支付授权码
154 | '''
155 | def ali_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
156 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="12",deviceType="05",amt = amt, orderno = orderno,channelAuthCode=channelAuthCode)
157 |
158 |
159 | '''
160 | 手Q被扫支付
161 | appId:商户应用id
162 | appKey:商户应用秘钥
163 | mhtOrderDetail:订单详情
164 | notifyUrl:商户后台通知URL
165 | isTest 是否测试 True 测试环境 False 生产环境
166 | amt:订单金额单位分,默认1分
167 | orderno:订单号(默认系统时间)
168 | channelAuthCode ; 支付授权码
169 | '''
170 | def handq_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
171 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="25",deviceType="05",amt = amt, orderno = orderno,channelAuthCode=channelAuthCode)
172 |
173 |
174 | '''
175 | 京东被扫支付
176 | appId:商户应用id
177 | appKey:商户应用秘钥
178 | mhtOrderDetail:订单详情
179 | notifyUrl:商户后台通知URL
180 | isTest 是否测试 True 测试环境 False 生产环境
181 | amt:订单金额单位分,默认1分
182 | orderno:订单号(默认系统时间)
183 | channelAuthCode ; 支付授权码
184 | '''
185 | def jd_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
186 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="04",deviceType="05",amt = amt, orderno = orderno,channelAuthCode=channelAuthCode)
187 |
188 |
189 |
190 | '''
191 | 银联被扫支付
192 | appId:商户应用id
193 | appKey:商户应用秘钥
194 | mhtOrderDetail:订单详情
195 | notifyUrl:商户后台通知URL
196 | isTest 是否测试 True 测试环境 False 生产环境
197 | amt:订单金额单位分,默认1分
198 | orderno:订单号(默认系统时间)
199 | channelAuthCode ; 支付授权码
200 | '''
201 | def union_trade05(appId,appKey,ordername,mhtOrderDetail,notifyUrl,channelAuthCode,amt = "1", orderno = '',isTest=True):
202 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,isTest=isTest,payChannelType="27",deviceType="05",amt = amt, orderno = orderno,channelAuthCode=channelAuthCode)
203 |
204 |
205 | '''
206 | 微信H5支付
207 | appId:商户应用id
208 | appKey:商户应用秘钥
209 | mhtOrderDetail:订单详情
210 | notifyUrl:商户后台通知URL
211 | frontNotifyUrl :商户前台通知URL
212 | isTest 是否测试 True 测试环境 False 生产环境
213 | amt:订单金额单位分,默认1分
214 | orderno:订单号(默认系统时间)
215 | outputType ; 0-公众号0模式
216 | '''
217 | def wx_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
218 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="13",deviceType="0601",amt = amt, orderno = orderno,outputType=outputType)
219 |
220 |
221 | '''
222 | 支付宝H5支付
223 | appId:商户应用id
224 | appKey:商户应用秘钥
225 | mhtOrderDetail:订单详情
226 | notifyUrl:商户后台通知URL
227 | frontNotifyUrl :商户前台通知URL
228 | isTest 是否测试 True 测试环境 False 生产环境
229 | amt:订单金额单位分,默认1分
230 | orderno:订单号(默认系统时间)
231 | outputType ; 0-公众号0模式
232 | '''
233 | def ali_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
234 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="12",deviceType="0601",amt = amt, orderno = orderno,outputType=outputType)
235 |
236 | '''
237 | 银联H5支付
238 | appId:商户应用id
239 | appKey:商户应用秘钥
240 | mhtOrderDetail:订单详情
241 | notifyUrl:商户后台通知URL
242 | frontNotifyUrl :商户前台通知URL
243 | isTest 是否测试 True 测试环境 False 生产环境
244 | amt:订单金额单位分,默认1分
245 | orderno:订单号(默认系统时间)
246 | outputType ; 0-公众号0模式
247 | '''
248 | def union_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
249 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="27",deviceType="0601",amt = amt, orderno = orderno,outputType=outputType)
250 |
251 | '''
252 | 手Q H5支付
253 | appId:商户应用id
254 | appKey:商户应用秘钥
255 | mhtOrderDetail:订单详情
256 | notifyUrl:商户后台通知URL
257 | frontNotifyUrl :商户前台通知URL
258 | isTest 是否测试 True 测试环境 False 生产环境
259 | amt:订单金额单位分,默认1分
260 | orderno:订单号(默认系统时间)
261 | outputType ; 0-公众号0模式
262 | '''
263 | def handq_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
264 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="12",deviceType="0601",amt = amt, orderno = orderno,outputType=outputType)
265 |
266 | '''
267 | 招行一网通 H5支付
268 | appId:商户应用id
269 | appKey:商户应用秘钥
270 | mhtOrderDetail:订单详情
271 | notifyUrl:商户后台通知URL
272 | frontNotifyUrl :商户前台通知URL
273 | isTest 是否测试 True 测试环境 False 生产环境
274 | amt:订单金额单位分,默认1分
275 | orderno:订单号(默认系统时间)
276 | outputType ; 0-公众号0模式
277 | '''
278 | def cmbywt_trade0601(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,outputType,amt = "1", orderno = '',isTest=True):
279 | return trade(appId,appKey,ordername,mhtOrderDetail,notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,payChannelType="17",deviceType="0601",amt = amt, orderno = orderno,outputType=outputType)
280 |
281 |
282 | '''
283 | 支付宝网页web支付
284 | appId:商户应用id
285 | appKey:商户应用秘钥
286 | mhtOrderDetail:订单详情
287 | notifyUrl:商户后台通知URL
288 | frontNotifyUrl :商户前台通知URL
289 | isTest 是否测试 True 测试环境 False 生产环境
290 | amt:订单金额单位分,默认1分
291 | orderno:订单号(默认系统时间)
292 | outputType:0.返回支付跳转链接 2.返回支付页面(html)
293 | '''
294 | def ali_trade04(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,amt = "1", orderno = '',outputType=0,isTest=True):
295 | return trade(appId,appKey,ordername,mhtOrderDetail,payChannelType="12",notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,deviceType="04",amt = amt, orderno = orderno,outputType=outputType)
296 |
297 | '''
298 | 银联网页web支付
299 | appId:商户应用id
300 | appKey:商户应用秘钥
301 | mhtOrderDetail:订单详情
302 | notifyUrl:商户后台通知URL
303 | frontNotifyUrl :商户前台通知URL
304 | isTest 是否测试 True 测试环境 False 生产环境
305 | amt:订单金额单位分,默认1分
306 | orderno:订单号(默认系统时间)
307 | outputType:0.返回支付跳转链接 2.返回支付页面(html)
308 | '''
309 | def union_trade04(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,amt = "1", orderno = '',outputType=0,isTest=True):
310 | return trade(appId,appKey,ordername,mhtOrderDetail,payChannelType="27",notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,deviceType="04",amt = amt, orderno = orderno,outputType=outputType)
311 |
312 |
313 | '''
314 | 微信小程序
315 | appId:商户应用id
316 | appKey:商户应用秘钥
317 | mhtOrderDetail:订单详情
318 | oriMhtOrderAmt:原始金额
319 | discountAmt:优惠金额
320 | notifyUrl:商户后台通知URL
321 | isTest 是否测试 True 测试环境 False 生产环境
322 | frontNotifyUrl :商户前台通知URL
323 | amt:订单金额单位分,默认1分
324 | orderno:订单号(默认系统时间)
325 | '''
326 | def wx_app(appId,appKey,ordername,mhtOrderDetail,notifyUrl,frontNotifyUrl,oriMhtOrderAmt,discountAmt,amt = "1", orderno = '',isTest=True):
327 | return trade(appId,appKey,ordername,mhtOrderDetail,payChannelType="13",notifyUrl=notifyUrl,frontNotifyUrl=frontNotifyUrl,isTest=isTest,deviceType="14",oriMhtOrderAmt=oriMhtOrderAmt,discountAmt=discountAmt,amt = amt, orderno = orderno,outputType="1")
328 |
329 |
330 | def trade(appId,appKey,ordername,mhtOrderDetail,payChannelType,deviceType,notifyUrl,isTest,outputType,frontNotifyUrl="", amt = "1", orderno = '',channelAuthCode='',oriMhtOrderAmt='',discountAmt=''):
331 | paypara = {
332 | 'funcode':'WP001',
333 | 'version': '1.0.0',
334 | 'appId':appId,
335 | 'mhtOrderType' :'01',
336 | 'mhtCurrencyType':'156',
337 | 'mhtOrderDetail':mhtOrderDetail,
338 | 'mhtOrderTimeOut':3600,
339 | 'notifyUrl':notifyUrl,
340 | 'mhtCharset': 'UTF-8',
341 | 'deviceType': deviceType,
342 | 'payChannelType' : payChannelType,
343 | 'outputType':outputType,
344 | 'mhtSignType':'MD5'
345 |
346 | }
347 | if len(frontNotifyUrl) > 0 :
348 | paypara["frontNotifyUrl"] = frontNotifyUrl
349 | if len(channelAuthCode) > 0:
350 | paypara['channelAuthCode']=channelAuthCode
351 | timestr = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
352 | if len(orderno) == 0:
353 | orderno = timestr + '_' +''.join(random.sample(string.ascii_letters, 16))
354 | paypara['mhtOrderStartTime'] = timestr
355 | paypara['mhtOrderNo'] = orderno
356 | paypara['mhtOrderName'] = ordername
357 | paypara['mhtOrderAmt'] = amt
358 | if len(oriMhtOrderAmt) > 0 :
359 | paypara["oriMhtOrderAmt"] = oriMhtOrderAmt
360 |
361 | if len(discountAmt) > 0 :
362 | paypara["discountAmt"] = discountAmt
363 | try:
364 | tradestr = interface.trade(appKey,paypara)
365 | except interface.APIInputError as ipse:
366 | print(ipse)
367 | except Exception as e:
368 | print(e)
369 | print(e.with_traceback)
370 | if isTest:
371 | url = testTradeUrl
372 | else:
373 | url = proTradeUrl
374 | resp = requests.post(url,tradestr)
375 | return urllib.parse.unquote(resp.text)
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/unpackMsg.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 | try:
4 | import sys
5 | reload(sys)
6 | sys.setdefaultencoding( "utf-8" )
7 | except Exception:
8 | pass
9 |
10 | # WP001-无插件聚合支付
11 | from ipaynowPythonSdk.ipaynow.paramlist import WP001_PostList, WP001_RespList
12 | # MQ001-商户支付订单查询
13 | from ipaynowPythonSdk.ipaynow.paramlist import MQ001_PostList, MQ001_RespList
14 | # N001-商户服务器端支付结果通知
15 | from ipaynowPythonSdk.ipaynow.paramlist import N001_QueryList, N001_RespList
16 | # N002-商户前端支付结果通知
17 | from ipaynowPythonSdk.ipaynow.paramlist import N002_NotifyList
18 |
19 | import ipaynowPythonSdk.ipaynow
20 | from ipaynowPythonSdk.ipaynow.error import APIInputError
21 | from ipaynowPythonSdk.ipaynow.md5Faced import md5calc
22 | from ipaynowPythonSdk.ipaynow.utils import trans2unicode
23 |
24 | try:
25 | from urllib import unquote
26 | except ImportError:
27 | from urllib.parse import unquote
28 |
29 | import getopt, sys
30 | def usage():
31 | print ('''
32 | NAME
33 | pack send message.
34 | Usage
35 | python packMsg.py [options]
36 | ''')
37 |
38 |
39 | class UnpackMsgRecv:
40 | __recvStr = ""
41 | __filterRule = []
42 | __apiKey = ""
43 | __unpackDict = {}
44 | __recvSortedList = []
45 | __md5Dict = {}
46 | __tarDictJoinMd5 = {}
47 | __md5Result = ""
48 | __tarListJoinMd5 = []
49 | __fromStrMd5 = ""
50 | def __init__(self, recvStr = "", filterrule = []):
51 | unicodestr = trans2unicode(recvStr)
52 | self.__recvStr = unquote(unicodestr)
53 | self.__filterRule = filterrule
54 | self.__apiKey = ipaynow.api_key
55 | def __recvStr2Dict(self):
56 | tempDict = {}
57 | tempList = self.__recvStr.split("&")
58 | for onpair in tempList:
59 | pairList = onpair.split("=")
60 | tempDict[pairList[0]] = pairList[1]
61 | self.__unpackDict = tempDict
62 | def __recvFilter(self):
63 | """from __unpackDict to __md5Dict.
64 | Use paramlist to filter the input dictionary.
65 | """
66 | for singleParam in self.__filterRule:
67 | filedName = singleParam['name']
68 | # judeg if the filedName exist in source dictionary.
69 | if filedName in self.__unpackDict: #exist
70 | # the filedName is exist in sourcedict.
71 | # then judge if the length is right.
72 | srcContent = self.__unpackDict[filedName]
73 | if ( len(str(srcContent)) > singleParam['len']):
74 | errmsg = '''Recv parameter [{}] is too long. Max length is [{}].'''.format(filedName,singleParam['len'])
75 | raise APIInputError(errmsg)
76 | if (len(str(srcContent)) == 0):
77 | continue
78 | # self.__tarDict[filedName] = srcContent
79 | # if the info needs md5 calc .
80 | if (singleParam['md5'] == 'Y'):
81 | self.__tarDictJoinMd5[filedName] = srcContent
82 | else : # no exist
83 | # judge if the parameter is mandatory
84 | if singleParam['mandatory'] == 'Y': # this parameter is mandatory
85 | if filedName == 'mhtSignature':
86 | continue
87 | errmsg = '''Didn't receive parameter [{}].this parameter indicts [{}].'''.format(filedName,singleParam['desp'])
88 | raise APIInputError(errmsg)
89 | else:
90 | continue
91 | def __sortDict(self, ):
92 | sortedListJoinmd5 = sorted(self.__tarDictJoinMd5.items(),key = lambda e: e[0],reverse = False)
93 | self.__tarListJoinMd5 = sortedListJoinmd5
94 | def __createFromStr(self):
95 | fromstrmd5 = ""
96 | for formContentMd5 in self.__tarListJoinMd5:
97 | if formContentMd5[1] == '' or formContentMd5[1] == None:
98 | continue
99 | fromstrmd5 += str(formContentMd5[0]) + "=" + str(formContentMd5[1]) + "&"
100 | self.__fromStrMd5 = fromstrmd5
101 | def __calcMd5(self):
102 | sourceString = self.__fromStrMd5
103 | securityKeyMd5 = md5calc(self.__apiKey.encode('utf-8'))
104 | sourceString += securityKeyMd5
105 | # print("待签名字符串:{}".format(sourceString))
106 | md5Result = md5calc(sourceString.encode('utf_8'))
107 | self.__md5Result = md5Result
108 | def getResultDict(self):
109 | self.__recvStr2Dict()
110 | return self.__unpackDict
111 | def verifyResponse(self):
112 | if not self.__unpackDict: # assert dictionary is exist.
113 | self.__recvStr2Dict()
114 | # start calc the md5 string
115 | self.__recvFilter()
116 | self.__sortDict()
117 | self.__createFromStr()
118 | self.__calcMd5()
119 | # print("calc md5 string:")
120 | #print(self.__md5Result)
121 | # print("signature:")
122 | # print(self.__unpackDict["signature"])
123 | return self.__md5Result == self.__unpackDict["signature"]
124 | def test(self):
125 | pass
126 | if __name__ == '__main__':
127 | try:
128 | opts, args = getopt.getopt(sys.argv[1:], "hf:", ["help", "file="])
129 | except getopt.GetoptError as err:
130 | # print help information and exit:
131 | print( str(err)) # will print something like "option -a not recognized"
132 | usage()
133 | sys.exit(2)
134 |
135 | file=""
136 |
137 | for o, a in opts:
138 | if o in ("-h", "--help"):
139 | usage()
140 | sys.exit()
141 | elif o in ("-f", "--file"):
142 | file= a
143 | else:
144 | assert False, "unhandled option"
145 | recvStr = '''mhtCharset=UTF-8&responseCode=A001&payChannelType=12&appId=1409801351286401&mhtOrderStartTime=20151102100843&mhtOrderNo=20151102100843_LAzqDtZklJhwmdBO&signType=MD5&mhtOrderAmt=10&transStatus=A001&mhtOrderTimeOut=120&mhtOrderName=ordername&deviceType=02&mhtOrderType=05&responseMsg=%E6%9F%A5%E8%AF%A2%E4%BA%A4%E6%98%93%E6%88%90%E5%8A%9F&signature=ad86ba36954dbde4b9f9aee97f4132c8&responseTime=20151102100954&mhtCurrencyType=156'''
146 | try:
147 | upmv = unpackMsgRecv(recvStr,MQ001_RespList)
148 | # resultStr = pms.getResultString()
149 | recvDict = upmv.getResultDict()
150 | print(recvDict)
151 | a = upmv.verifyResponse()
152 | print(a)
153 | #upmv.test()
154 | except APIInputError as e:
155 | print("api error occured")
156 | print(e.with_traceback)
157 | except Exception as e:
158 | print("other exception")
159 | print(e.with_traceback)
160 |
161 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
2 |
3 | import os
4 | import io
5 | import sys
6 |
7 | __all__ = ['StringIO', 'parse_qsl', 'trans2unicode']
8 |
9 |
10 |
11 | try:
12 | # When cStringIO is available
13 | import cStringIO as StringIO
14 | except ImportError:
15 | from io import StringIO
16 |
17 | try:
18 | from urlparse import parse_qsl
19 | except ImportError:
20 | # Python < 2.6
21 | from cgi import parse_qsl
22 |
23 |
24 |
25 | def trans2unicode(value):
26 | '''via this function ,every string will trans to unicode string'''
27 | if sys.version_info >= (3,0,0):
28 | # for Python 3
29 | if isinstance(value, bytes):
30 | return value.decode('utf_8') # or s = str(s)[2:-1]
31 | else:
32 | return value
33 | else:
34 | # for Python 2
35 | if isinstance(value, unicode):
36 | return str(value)
37 | else:
38 | return unicode(value)
39 |
--------------------------------------------------------------------------------
/ipaynowPythonSdk/ipaynow/version.py:
--------------------------------------------------------------------------------
1 | VERSION = '1.0.0'
--------------------------------------------------------------------------------
/ipaynowPythonSdk/setup.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import warnings
4 |
5 | from ipaynow import VERSION
6 |
7 | try:
8 | from setuptools import setup
9 | except ImportError:
10 | from distutils.core import setup
11 |
12 | try:
13 | from distutils.command.build_py import build_py_2to3 as build_py
14 | except ImportError:
15 | from distutils.command.build_py import build_py
16 |
17 | path, script = os.path.split(sys.argv[0])
18 | os.chdir(os.path.abspath(path))
19 |
20 |
21 | if sys.version_info < (2, 6):
22 | warnings.warn(
23 | 'Python 2.5 is no longer officially supported by ipaynow. '
24 | 'If you have any questions, please contact us at www.ipaynow.cn.',
25 | DeprecationWarning)
26 |
27 |
28 |
29 | # Don't import ipaynow module here, since deps may not be installed
30 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'ipaynow'))
31 |
32 |
33 | setup(
34 | name='ipaynow',
35 | cmdclass={'build_py': build_py},
36 | version=VERSION,
37 | description='ipaynow python bindings',
38 | author='ipaynow',
39 | author_email='www.ipaynow.com',
40 | url='https://pay.ipaynow.cn/',
41 | packages=['ipaynow'],
42 | classifiers=[
43 | "Development Status :: 5 - Production/Stable",
44 | "Intended Audience :: Developers",
45 | "License :: OSI Approved :: MIT License",
46 | "Operating System :: OS Independent",
47 | "Programming Language :: Python",
48 | "Programming Language :: Python :: 2",
49 | "Programming Language :: Python :: 2.6",
50 | "Programming Language :: Python :: 2.7",
51 | "Programming Language :: Python :: 3",
52 | "Programming Language :: Python :: 3.2",
53 | "Programming Language :: Python :: 3.3",
54 | "Programming Language :: Python :: 3.4",
55 | "Programming Language :: Python :: 3.5",
56 | "Programming Language :: Python :: Implementation :: PyPy",
57 | "Topic :: Software Development :: Libraries :: Python Modules",
58 | ])
59 |
--------------------------------------------------------------------------------