Python django drf 接入paypal支付
PayPal API是基于HTTP的restful API,使用OAuth 2.0进行授权。API请求和响应主体采用json格式
1,注册paypal账号 (1)在浏览器输入“https://www.paypal.com” 页面跳转,进行注册
(2)选择“创建个人账户”,根据要求填写信息,注册完去邮箱激活
2,注册paypal开发者账号
(1)在浏览器输入 https://developer.paypal.com
并登陆创建好的账号登录
3,创建两个测试用户 (1)登录成功之后,点击Sandbox下的Accounts
(2) 进入Accounts洁面后,可以看到系统有两个生成好的测试账号,但是我们不要用系统给的测试账号,很卡,自己创建两个账号
3)点击“Create Account” , 创建测试用户
填完账户信息即可, 先创建一个“ PERSONAL”类型的用户,国家一定要选“China”,账户余额自己填写。接着创建一个“BUSINESS”类型的用户,国家一定要选“China”,账户余额自己填写,创建好之后可以点击测试账号下的”Profile“,可以查看信息,如果没加载出来,刷新 。
用测试账号登录测试网站查看,注意!这跟paypal官网不同!不是同一个地址,在浏览器输入:https://www.sandbox.paypal.com 在这里登陆测试账户
4,创建应用,生成用于测试的clientID 和密钥
创建应用时,PayPal会为沙盒和实时环境为您的应用生成一组OAuth客户端ID和机密凭据。您Authorization在get访问令牌请求中的标头中传递这些凭据。通过持票人令牌,您可以代表资源所有者并获得资源所有者的批准。
(1)点击左边导航栏Dashboard下的My Apps & Credentials,创建一个账号,下图是我已经创建好的
(2) 然后创建App
3)点击刚创建的App, 注意看到”ClientID“ 和”Secret“(Secret如果没显示,点击下面的show就会看到,点击后show变为hide)
安装paypalrestsdk,有了sdk简单快捷
pip install paypalrestsdk
初始化paypal对象
import paypalrestsdk
import requests
clientId = 'AdFjgHUeuz****************-BDdx386kLYFJruoBmhza****************'
clientSecret = 'ELEdh****************GA90pAbWi_5XMmYaAVx4TifupxPoK10gW-****************'
paypalrestsdk.configure({
"mode": "sandbox", # sandbox or live
"client_id": clientId,
"client_secret": clientSecret})
class PayPal(object):
"""
paypal接口
"""
def __init__(self, money, currency, description):
self.intent = "sale"
self.payer = {"payment_method": "paypal"}
self.redirect_urls = {"return_url": "http://localhost:8000/payment/execute",
"cancel_url": "http://localhost:8000/"}
self.transactions = [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": money,
"currency": "USD",
"quantity": 1}]},
"amount": {
"total": money,
"currency": CURRENCY_TAG[currency]},
"description": description,
}]
def get_url(self):
payment = paypalrestsdk.Payment({
"intent": self.intent,
"payer": self.payer,
"redirect_urls": self.redirect_urls,
"transactions": self.transactions})
if payment.create():
payment_id = payment.id
for link in payment.links:
if link.rel == "approval_url":
approval_url = str(link.href)
return payment_id, approval_url
else:
print("paypal服务器错误")
return None
在生成自己网站订单的时候,获取paypal的支付链接,一起返回给前端,让前端跳转 这是订单生成的序列化器
class RechargeRecodeSerializer(serializers.ModelSerializer):
order_id = serializers.CharField(read_only=True)
paypal_url = serializers.SerializerMethodField(read_only=True)#增加支付跳转的字段,需要返回给前端
class Meta:
model = FundRecord
# 指明校验的或者序列化输出字段
fields = ("order_id", "currency", "trade_type", "money", "remarks", "fees")
def get_paypal_url(self, obj):
paypal = PayPal(self.validated_data["money"], self.validated_data["currency"], "test,,,,test")
try:
payment_id ,approval_url = paypal.get_url()
except:
payment_id = None
approval_url = None
if all((payment_id,approval_url)):
obj.payment_id = payment_id
obj.save()
return approval_url
前端获取到支付链接,进行跳转到paypal支付界面,用户输入支付密码之后,跳转回来预先填写的回调地址return_url": "http://localhost:8000/payment/execute
处理支付返回
paypal支付返回 url('payment/execute', views.PaypalView.as_view()),
class PaypalView(APIView):
def get(self,request):
payment_id = self.request.GET.get("paymentId")
payer_id = self.request.GET.get("PayerID")
try:
payment = Payment.find(payment_id)
except:
return Response("err")
try:
record_obj = FundRecord.objects.get(payment_id = payment_id)
except:
return Response("err")
if payment.execute({"payer_id": str(payer_id)}):
print("Payment execute successfully")
record_obj.trade_state = 1
record_obj.pay_time = datetime.datetime.now()
record_obj.save()
CapitalAccount.objects.filter(seller_id = record_obj.seller_id, currency = record_obj.currency).update(
available_balance = F("available_balance")+record_obj.money)
return Response("ok")
else:
print(payment.error) # Error Hash
return Response("err")
至此完成paypal支付