django实现支付宝付款功能

支付宝支付功能

登录支付宝官网开发平台

下载SDK,

支付宝并没有python版本SDK

SDK有实例和代码。

没有python则自己写,或者去github找。

本次利用alipay这个组件。

先安装一个pycrytodome

pip3 install pycrytodome

如果真实环境,按上面这个来注册。

测试环境需要用沙箱环境。

向支付宝提交的这个链接,在测试模式有dev,生产环境删掉dev

公钥复制到支付宝里,私钥存到自己django文件中,自己文件的公钥是来自支付宝的公钥。

上面沙箱环境不需要配置。

下面是创建一个生产环境的应用。

以下为支持的功能

以上为真实生产需要的操作。

然后之后看pay项目代码。

以上为目录结构。

views.py:

 1 from django.shortcuts import render, redirect, HttpResponse
 2 from utils.pay import AliPay
 3 import json
 4 import time
 5
 6
 7 def ali():
 8     # 商户app_id
 9     app_id = "2016082600312402" #复制来自支付宝生成的id
10     # 服务器异步通知页面路径 需http: // 格式的完整路径,不能加?id = 123 这类自定义参数,必须外网可以正常访问
11     # 发post请求
12     notify_url = "http://www.xxxx.com:8009/page2/"  #将这两个链接复制到支付宝中
13
14     # 页面跳转同步通知页面路径 需http: // 格式的完整路径,不能加?id = 123 这类自定义参数,必须外网可以正常访问
15     # 发get请求
16     return_url = "http://www.xxxx.com:8009/page2/"
17     # 商户私钥路径
18     merchant_private_key_path = "keys/pri"   #设置公钥和私钥的地址,文件上下两行begin和end是必须的,公钥就放在第二行。
19     # 支付宝公钥路径
20     alipay_public_key_path = "keys/pub"
21
22     alipay = AliPay(
23         appid=app_id,
24         app_notify_url=notify_url,
25         return_url=return_url,
26         app_private_key_path=merchant_private_key_path,
27         alipay_public_key_path=alipay_public_key_path,  # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥
28         debug=True,  # 默认False,
29     )
30     return alipay
31
32
33 def page1(request):
34     if request.method == "GET":
35         return render(request, ‘page1.html‘)
36     else:
37         money = float(request.POST.get(‘money‘))
38         alipay = ali()
39         # 生成支付的url
40         query_params = alipay.direct_pay(
41             subject="充气式减压玩具",  # 商品简单描述
42             out_trade_no="x2" + str(time.time()),  # 商户订单号
43             total_amount=money,  # 交易金额(单位: 元 保留俩位小数)
44         )
45
46         pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
47         #支付宝网关链接,去掉dev就是生产环境了。
48         return redirect(pay_url)
49
50
51 def page2(request):
52     alipay = ali()
53     if request.method == "POST":
54         # 检测是否支付成功
55         # 去请求体中获取所有返回的数据:状态/订单号
56         from urllib.parse import parse_qs
57
58         # request.body                  => 字节类型
59         # request.body.decode(‘utf-8‘)  => 字符串类型
60         """
61         {"k1":["v1"],"k2":["v1"]}
62         k1=[v1]&k2=[v2]
63         """
64         body_str = request.body.decode(‘utf-8‘)
65         post_data = parse_qs(body_str)
66         # {k1:[v1,],k2:[v2,]}
67
68         # {k1:v1}
69         post_dict = {}
70         for k, v in post_data.items():
71             post_dict[k] = v[0]
72
73
74         print(post_dict)
75         """
76         {‘gmt_create‘: ‘2017-11-24 14:53:41‘, ‘charset‘: ‘utf-8‘, ‘gmt_payment‘: ‘2017-11-24 14:53:48‘, ‘notify_time‘: ‘2017-11-24 14:57:05‘, ‘subject‘: ‘充气式韩红‘, ‘sign‘: ‘YwkPI9BObXZyhq4LM8//MixPdsVDcZu4BGPjB0qnq2zQj0SutGVU0guneuONfBoTsj4XUMRlQsPTHvETerjvrudGdsFoA9ZxIp/FsZDNgqn9i20IPaNTXOtQGhy5QUetMO11Lo10lnK15VYhraHkQTohho2R4q2U6xR/N4SB1OovKlUQ5arbiknUxR+3cXmRi090db9aWSq4+wLuqhpVOhnDTY83yKD9Ky8KDC9dQDgh4p0Ut6c+PpD2sbabooJBrDnOHqmE02TIRiipULVrRcAAtB72NBgVBebd4VTtxSZTxGvlnS/VCRbpN8lSr5p1Ou72I2nFhfrCuqmGRILwqw==‘, ‘buyer_id‘: ‘2088102174924590‘, ‘invoice_amount‘: ‘666.00‘, ‘version‘: ‘1.0‘, ‘notify_id‘: ‘11aab5323df78d1b3dba3e5aaf7636dkjy‘, ‘fund_bill_list‘: ‘[{"amount":"666.00","fundChannel":"ALIPAYACCOUNT"}]‘, ‘notify_type‘: ‘trade_status_sync‘, ‘out_trade_no‘: ‘x21511506412.4733646‘, ‘total_amount‘: ‘666.00‘, ‘trade_status‘: ‘TRADE_SUCCESS‘, ‘trade_no‘: ‘2017112421001004590200343962‘, ‘auth_app_id‘: ‘2016082500309412‘, ‘receipt_amount‘: ‘666.00‘, ‘point_amount‘: ‘0.00‘, ‘app_id‘: ‘2016082500309412‘, ‘buyer_pay_amount‘: ‘666.00‘, ‘sign_type‘: ‘RSA2‘, ‘seller_id‘: ‘2088102172939262‘}
77         {‘stade_status‘: "trade_success",‘order‘:‘x2123123123123‘}
78         """
79         sign = post_dict.pop(‘sign‘, None)
80
81         status = alipay.verify(post_dict, sign)
82         if status:
83             print(post_dict[‘stade_status‘])
84             print(post_dict[‘out_trade_no‘])
85
86         return HttpResponse(‘POST返回‘)
87     else:
88         # QueryDict = {‘k‘:[1],‘k1‘:[11,22,3]}
89         params = request.GET.dict()
90         sign = params.pop(‘sign‘, None)
91         status = alipay.verify(params, sign)
92         print(‘GET验证‘, status)
93         return HttpResponse(‘支付成功‘)

key目录

-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZWExNxlfrbIknZmVwzK8MNYkP8aW2XChMNUD/+Gi3OC/k417Q6C326nxlYQy3FbsjPBofVapbeHY2y0J3t3m1tIuH3MBDqAM2pt3mExl7xr8hBROfD71V39XplJhE2WRPN2BdJLiYVYXgTTkpXunA1zsbt0gdmQK2VoQj3cdy7EukUferBRwsxxIe0neCPWwq4DlQeHu94csA3smXZLyOt8fovd4ksiphQ3U5R/aNCxV0vY47zSWK+jYKQUzpbRidVeQX3nT9G6M8w7b5rlCB1VZQBLwiVfYCVNTxcTN8qI5NaMvbWeKrr0YNRTKKzn2qL4CKLuyDoCMXo+cyDnnFAgMBAAECggEAFqTobkH37wND1uMINpRcuHzrZsnaZgF8AVSbDRAoeM5VzxcRTdqiz1Lm2vkdhgWxlZ4xaopWUWlfh53tsuNevtusnd8V+PaMPylrfQkIYqj2SM5qmOve4g+MDeX5Z1Lu7IHsfEfTI6vlYtUo23KUEA9cjSqvTMYgTjb9VW9J1GMw5ccPkret2Emp1ThzaUzaetcGkSbllFuHSlwZ2fu6egxQPNZHDmyuH708cxW8FyB7ilR23cMqTXh4u5ytEEkt6mRb9xman8D7yaE7JEBlXSKCvZBDv73qsuEIHSI3tomLIB5l0kxV58gq90giTnPnwcwn4ylJypUMfTr8O6JFAQKBgQDvzrUOM0XrPhg8aP5suzvV/MhP3z+F4Fm7Z5eBS3HiGq1lYzqhzjCE9bZ7uXwYbvLvLf8lpWsubeU/dO0Ts6yfm4yr43sOsIpuBWoQK+MQIriDkeMeld4+adbEFFxyPSATdpEvz8pUqsWAdTAF5/kawQXtUiSbbPLHtDNf3Nc/MQKBgQDoBU4gcLnrzA7i8xSn4YqEpR0brQGE0L4QRx4IVLzYvKv3swJqM9+B3ICrgJ1B9zr+IPN0DTu4ZunWyVDmFxLfwMNuqg5zmHeUf+XYY3toDm7co1LoFXp5oMA9n6fYKlcTvz1d7mK0sQ0P2adWFLp1cX0yEEEFNVCPV8L1KcfG1QKBgHT8TwEdbDeFdEdMJQogEOGkTogAbbm+p6evso5Fosndn8c9MCYtMyg5wgr7gplczrB1rOnNl8rvm41oWhtpZIX8WRSlhau13eIsTACVmFCPz5mHutd53xBti3LeR/cG8LXt+ofrg1XodS7kfEf1UWWG0oBiuS8FaC6aLxHN50eRAoGBAJv4tQRpwxIYIwm9ju0sWQnCVUb9jj/Sc3JN3IqNLEYmzxO8aqsqI94QdQ7VbuGhaS7cx8wD+VmFFT0mKBQE/tMbqkUCXKSoofpZ4BEPDy5sRWpdAKaziZmpzpGeeh5+l/rWXFKApioBu14kWrErTg0VNawp8QunQ3iY7p4QcBPhAoGADWv4kbu6ln/mO85t9/8KtNS883J+EWqg6RzyC+1l1UhM3+k7gjCPqaBtb4yGas2bkcSPbl8oq7inSWfCap5zmTkzcrrS3BxQuHH4XDRoqB/vrGHP5gD+KpfZxD+rFscfjVlk5FwhnYHrlRzE/kZr+MGOrtvc9TaluYzR0g18/dU=
-----END RSA PRIVATE KEY-----

pri 私钥

1 -----BEGIN PUBLIC KEY-----
2 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstVlLwOTcg64SiT4GiHOlToRxz88r3zjWX2N1juX86fa+UYtq33TfXZgh1rVl67dLJC7ICh4BYCrq1+JkMiyah0oOC6EVdLBWcKDrNV19ig5oetTuEO3Vbji/rU3nUYun24MmOJKca3xf4UL192pM5w+/mNHPLLHJBeoMjDWVJehURRw/PDGLv6+QFnC9LwihcR5vWr7x0lBAGJsPqRv9RUB0UWXj/AzxDeD6GGlHMS4tYwwYi6JQRHf9yA+dWDD4YTUc3UBb/WQx954ET/BW+KTFQzNwxryqr3XmucnZmkiNfTkmdGoH+J0zpVXSqHAvLkFJ9UERYUrUq0Bz6CpqQIDAQAB
3 -----END PUBLIC KEY-----

pub 公钥文件

settings文件

DEBUG = True

ALLOWED_HOSTS = [‘*‘]
MIDDLEWARE = [
    ‘django.middleware.security.SecurityMiddleware‘,
    ‘django.contrib.sessions.middleware.SessionMiddleware‘,
    ‘django.middleware.common.CommonMiddleware‘,
    # ‘django.middleware.csrf.CsrfViewMiddleware‘,
    ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,
    ‘django.contrib.messages.middleware.MessageMiddleware‘,
    ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,
]#注意以上

settings

url

from django.conf.urls import url
from django.contrib import admin
from app import views
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^page1/‘, views.page1),
    url(r‘^page2/‘, views.page2),
]

url

html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <link rel="stylesheet" href="dist/css/bootstrap.css">
 7 </head>
 8 <body>
 9     <form method="POST">
10         {% csrf_token %}
11         <input type="text" name="money">
12         <input type="submit" value="去支付" />
13     </form>
14
15
16 <script></script>
17 </body>
18 </html>

html

utils

  1 from datetime import datetime
  2 from Crypto.PublicKey import RSA
  3 from Crypto.Signature import PKCS1_v1_5
  4 from Crypto.Hash import SHA256
  5 from urllib.parse import quote_plus
  6 from urllib.parse import urlparse, parse_qs
  7 from base64 import decodebytes, encodebytes
  8 import json
  9
 10 class AliPay(object):
 11     """
 12     支付宝支付接口(PC端支付接口)
 13     """
 14
 15     def __init__(self, appid, app_notify_url, app_private_key_path,
 16                  alipay_public_key_path, return_url, debug=False):
 17         self.appid = appid
 18         self.app_notify_url = app_notify_url
 19         self.app_private_key_path = app_private_key_path
 20         self.app_private_key = None
 21         self.return_url = return_url
 22         with open(self.app_private_key_path) as fp:
 23             self.app_private_key = RSA.importKey(fp.read())
 24         self.alipay_public_key_path = alipay_public_key_path
 25         with open(self.alipay_public_key_path) as fp:
 26             self.alipay_public_key = RSA.importKey(fp.read())
 27
 28         if debug is True:
 29             self.__gateway = "https://openapi.alipaydev.com/gateway.do"
 30         else:
 31             self.__gateway = "https://openapi.alipay.com/gateway.do"
 32
 33     def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):
 34         biz_content = {
 35             "subject": subject,
 36             "out_trade_no": out_trade_no,
 37             "total_amount": total_amount,
 38             "product_code": "FAST_INSTANT_TRADE_PAY",
 39             # "qr_pay_mode":4
 40         }
 41
 42         biz_content.update(kwargs)
 43         data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)
 44         return self.sign_data(data)
 45
 46     def build_body(self, method, biz_content, return_url=None):
 47         data = {
 48             "app_id": self.appid,
 49             "method": method,
 50             "charset": "utf-8",
 51             "sign_type": "RSA2",
 52             "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
 53             "version": "1.0",
 54             "biz_content": biz_content
 55         }
 56
 57         if return_url is not None:
 58             data["notify_url"] = self.app_notify_url
 59             data["return_url"] = self.return_url
 60
 61         return data
 62
 63     def sign_data(self, data):
 64         data.pop("sign", None)
 65         # 排序后的字符串
 66         unsigned_items = self.ordered_data(data)
 67         unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)
 68         sign = self.sign(unsigned_string.encode("utf-8"))
 69         # ordered_items = self.ordered_data(data)
 70         quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)
 71
 72         # 获得最终的订单信息字符串
 73         signed_string = quoted_string + "&sign=" + quote_plus(sign)
 74         return signed_string
 75
 76     def ordered_data(self, data):
 77         complex_keys = []
 78         for key, value in data.items():
 79             if isinstance(value, dict):
 80                 complex_keys.append(key)
 81
 82         # 将字典类型的数据dump出来
 83         for key in complex_keys:
 84             data[key] = json.dumps(data[key], separators=(‘,‘, ‘:‘))
 85
 86         return sorted([(k, v) for k, v in data.items()])
 87
 88     def sign(self, unsigned_string):
 89         # 开始计算签名
 90         key = self.app_private_key
 91         signer = PKCS1_v1_5.new(key)
 92         signature = signer.sign(SHA256.new(unsigned_string))
 93         # base64 编码,转换为unicode表示并移除回车
 94         sign = encodebytes(signature).decode("utf8").replace("\n", "")
 95         return sign
 96
 97     def _verify(self, raw_content, signature):
 98         # 开始计算签名
 99         key = self.alipay_public_key
100         signer = PKCS1_v1_5.new(key)
101         digest = SHA256.new()
102         digest.update(raw_content.encode("utf8"))
103         if signer.verify(digest, decodebytes(signature.encode("utf8"))):
104             return True
105         return False
106
107     def verify(self, data, signature):
108         if "sign_type" in data:
109             sign_type = data.pop("sign_type")
110         # 排序后的字符串
111         unsigned_items = self.ordered_data(data)
112         message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)
113         return self._verify(message, signature)

utils

如果需要测试,需要用公网可以直接访问的url,

我们可以通过自己单机测试,更改本机hosts文件,将本机ip和views里return_url一致。

更改C:\Windows\System32\drivers\etc\hosts

最后从支付宝下载对应的沙河手机app,充值之后就可以付款了,快去尝试吧。

时间: 2024-08-29 11:03:10

django实现支付宝付款功能的相关文章

11. PHP接入微信企业付款功能

payment 项目2.0版本 这个功能与支付宝的批量付款到支付宝帐号功能类似.但是当前支付宝这个接口已经停止审核了. 当前很多提问平台就用到了这两个平台.比如[来问医生],你提的问题如果被人看了.医生得0.5元,你得0.5元.然后累积够1元后,[来问医生]就会通过微信的企业付款功能给你的微信余额增加1元. 代码调用 use Payment\TransferContext; use Payment\Common\PayException; use Payment\Config; // 生成转款单

SpringSide集成支付宝支付功能

网络购物很流行,那么最流行的支付手段估计应该是支付宝了,那么怎么样将支付宝集成到自己的环境中呢,今天我来讲一下如何在springside框架中集成支付宝支付功能. 首先,我们去支付宝商家服务页面去注册和申请支付功能,并在那里下载sdk开发包https://b.alipay.com/order/productDetail.htm?productId=2012111200373124,这个是支付宝的即时到账收款功能,然后下面有一个流程的介绍,我们选择下面的技术集成,先下载sdk开发包,下载完成之后解

支付宝支付功能

每篇一语:理想很丰满,现实很骨感! 1.alipay 双功能支付简介 2.alipay 提交支付订单 3.alipay 整合双功能支付及发货信息同步 4.alipay 页面跳转同步通知处理 5.alipay 服务器异步通知处理   ======================  华丽丽的分割线  ======================   1.alipay 双功能支付简介   1.0 废话 网上copy的东西那么多,查个东西在百度上google一下都搜不到个完整,我恨!代码还是看自己整理的

Thinkphp集成手机支付宝接口功能

最近做微商城,需要实现手机wap支付功能,选择的是支付宝的接口支付功能.这里是我用的是支付宝“手机网站支付”产品(注:该产品要支付宝企业账号才能申请),具体步骤如下: 一.下载支付宝接口包 https://b.alipay.com/order/productDetail.htm?productId=2013080604609688 二.重新整理接口包文件 下载下来的接口包文件有很多语言的源码 注:openssl用来生成公私钥,RSA签名才使用.这里我们用的MD5签名,所有该文件用不到. 我们选择

Spring MVC+Spring+Mybatis实现支付宝支付功能(图文详解)

前言 本教程详细介绍了如何使用ssm框架实现支付宝支付功能.本文章分为两大部分,分别是「支付宝测试环境代码测试」和「将支付宝支付整合到ssm框架」,详细的代码和图文解释,自己实践的时候一定仔细阅读相关文档,话不多说我们开始. 本教程源代码: https://github.com/OUYANGSIHAI/sihai-maven-ssm-alipay 一.支付宝测试环境代码测试 1. 下载电脑网站的官方demo: 下载:https://docs.open.alipay.com/270/106291/

支付宝支付功能(使用支付宝sdk)

1.准备参数        新建一个公共参数配置类NewAlipayconfig (可将参数存放到config配置文件中读取)          public class NewAlipayconfig { public NewAlipayconfig() { // // TODO: 在此处添加构造函数逻辑 // } // 应用ID,您的APPID public static string app_id = "1231213"; // 支付宝网关 public static strin

ios集成支付宝的功能

1.很多的项目现在要集成第三方的sdk来完成,今天我看了一下支付宝,应用了支付宝的功能,接下来给大家讲解下如何集成支付宝: 2.首先要和支付宝签约:(支持企业的账号),邮件得到一系列的东西:(所有的值在支付宝回复的邮件里面:注意,建议除appScheme以外的字段都从服务器请求): 3.第二你要下载AlipaySDK包,支付宝中心下载: 4.将你的下载的sdk导入到你的项目中去: 5.然后运行一下会报错,一个是order.h 还有一个是:找不到rsa.h文件: 解决方案: order.h 的解决

如何取消Paypal自动付款功能

在国外在线服务消费肯定会常遇到PayPal的支付方式,有些人可能PayPal有些余额可能会用这个工具来支付,但付款后,可能服务因为不满意而退掉,但第二年却自动续约了?但明明服务已退掉,这该怎么处理呢?难不成白白让它扣款吗?其实,这个PayPal自动续约付款功能是可以关闭的.在PayPal中这叫做「付款约定」,只要取消,就可以避免来年自动续约. 1.首先请登录Paypal账户,然后来到[个人档案]→[个人档案和设定] 2.接着点选左侧[销售工具],接着找到右侧「我的自动付款」,然后点一下后方的「更

GoDaddy用支付宝付款时出现我们无法处理这笔交易,请查看您的付款信息并重试。

一.GoDaddy操作流程 在GoDaddy上购买及注册域名的操作步骤,请参考https://www.jianshu.com/p/05289a4bc8b2进行操作. 二.我遇到的问题 今天用GoDaddy购买域名,下单准备用支付宝付款时系统提示"我们无法处理这笔交易.请查看您的付款信息并重试." 如下图所示 三.解决办法 在尝试过https://www.dute.me/godaddy-alipay.html提到的所有方法后终于完成了支付! 办法:将下单付款页面拉至最底下,有两个选项[国