django实现paypal订阅记录

embedded/2024/11/29 17:13:17/

开发者链接  登录开发者

沙箱账号链接 沙箱账号链接


1. 创建沙箱应用

2. 记录 Client ID和 Secret 后面有用 然后点击进去创建回调url和回调事件,可以全选事件也可以选择你需要的

3.拿沙箱账号信息去登录

4.登录后创建订阅产品内容。记住产品id

5.配置django后端信息和创建订阅链接进行支付

python">import requests
from datetime import datetime# 配置 PayPal 凭据和环境
PAYPAL_CLIENT_ID_SANDBOX = '沙箱SANDBOX'
PAYPAL_SECRET_KEY_SANDBOX = '沙箱密钥'
PAYPAL_CLIENT_ID_PRODUCTION = ''  # 替换为实际生产环境的客户端 ID
PAYPAL_SECRET_KEY_PRODUCTION = ''  # 替换为实际生产环境的密钥
PAYPAL_MODE = 'sandbox'  # 'sandbox' 或 'live'
PAYPAL_BASE_URL = "https://api.sandbox.paypal.com" if PAYPAL_MODE == "sandbox" else "https://api.paypal.com"# 工具函数:生成自定义订单号
def generate_order_id():"""根据当前时间生成唯一订单号格式:P-YYYYMMDD-HHMMSS"""current_time = datetime.now().strftime("%Y%m%d-%H%M%S")return f"P-{current_time}"# 工具函数:获取 PayPal 访问令牌
def get_paypal_access_token():"""获取 PayPal API 访问令牌"""url = f"{PAYPAL_BASE_URL}/v1/oauth2/token"auth = (PAYPAL_CLIENT_ID_SANDBOX, PAYPAL_SECRET_KEY_SANDBOX)headers = {"Accept": "application/json", "Accept-Language": "en_US"}data = {"grant_type": "client_credentials"}response = requests.post(url, headers=headers, data=data, auth=auth)if response.status_code == 200:return response.json().get("access_token")else:raise Exception(f"获取访问令牌失败: {response.text}")# 创建 PayPal 订阅链接
def create_paypal_subscription_link(plan_id):"""使用 PayPal API 创建订阅链接:param plan_id: 示例计划 ID (如: P-4KL07437GC7241026M5AW2JY):return: 订阅链接 URL"""try:# 获取访问令牌access_token = get_paypal_access_token()# PayPal 订阅 API URLsubscription_url = f"{PAYPAL_BASE_URL}/v1/billing/subscriptions"# 自定义订单号custom_order_id = generate_order_id()# 构建订阅请求的 payloadpayload = {"plan_id": plan_id,"custom_id": custom_order_id,"application_context": {"brand_name": "Your Brand Name","user_action": "SUBSCRIBE_NOW","landing_page": "BILLING","return_url": f"支付成功跳转的url","cancel_url": f"取消支付跳转的url",}}headers = {"Authorization": f"Bearer {access_token}","Content-Type": "application/json"}# 发送请求以创建订阅response = requests.post(subscription_url, json=payload, headers=headers)if response.status_code in [200, 201]:# 提取审批链接subscription_data = response.json()approval_url = next(link["href"] for link in subscription_data["links"] if link["rel"] == "approve")print(f"订阅链接生成成功: {approval_url}")return approval_urlelse:print(f"创建订阅链接失败: {response.text}")return Noneexcept Exception as e:print(f"创建订阅链接时发生错误: {e}")return None# 示例调用
if __name__ == "__main__":PLAN_ID = "P-4KL07437GC7241026M5AW2JY"  # 示例计划 IDapproval_url = create_paypal_subscription_link(PLAN_ID)if approval_url:print(f"请访问以下链接以完成订阅: {approval_url}")else:print("无法生成订阅链接,请检查配置或 API 调用。")

6.订阅成功后回调

当用户进入approval_url 付款成功后会回调到给个前面创建的回调链接。测试付款的账号也在开发者后台生成自行付款测试。最后后端再根据不同的回调类型操作数据库即可

python">def paypal_webhook(request):"""PayPal Webhook 回调入口"""try:# 解析请求体webhook_data = json.loads(request.body.decode("utf-8"))print("[Webhook] 收到数据:", json.dumps(webhook_data, indent=4))event_type = webhook_data.get("event_type")resource = webhook_data.get("resource")webhook_id = webhook_data.get("id")print(f"[Webhook] 事件类型: {event_type}, Webhook ID: {webhook_id}")handle_webhook_event(event_type, resource, webhook_id)except Exception as e:print(f"[Webhook] 错误: {str(e)}")return JsonResponse({"code": 500, "message": f"服务器错误: {str(e)}"})def handle_webhook_event(event_type, resource, webhook_id):"""处理 PayPal Webhook 回调事件:param event_type: 回调事件类型(如 BILLLING.SUBSCRIPTION.ACTIVATED):param resource: 事件的资源数据(JSON 格式):param webhook_id: PayPal Webhook ID,用于验证请求合法性"""print(f"[Webhook 回调] 收到事件: {event_type}, Webhook ID: {webhook_id}")if event_type == "BILLING.SUBSCRIPTION.ACTIVATED":# 处理订阅激活事件print("[Webhook 回调] 事件类型: 订阅已激活")print(f"[Webhook 回调] 资源数据: {resource}")handle_subscription_activated(resource, webhook_id)elif event_type == "BILLING.SUBSCRIPTION.UPDATED":# 处理订阅更新事件print("[Webhook 回调] 事件类型: 订阅已更新")print(f"[Webhook 回调] 资源数据: {resource}")handle_subscription_updated(resource, webhook_id)elif event_type == "BILLING.SUBSCRIPTION.CANCELLED":# 处理订阅取消事件print("[Webhook 回调] 事件类型: 订阅已取消")print(f"[Webhook 回调] 资源数据: {resource}")handle_subscription_cancelled(resource, webhook_id)elif event_type == "PAYMENT.SALE.COMPLETED":# 处理付款完成事件print("[Webhook 回调] 事件类型: 付款已完成")print(f"[Webhook 回调] 资源数据: {resource}")handle_payment_completed(resource, webhook_id)else:# 未知的事件类型print(f"[Webhook 回调] 未知事件类型: {event_type}")print(f"[Webhook 回调] 资源数据: {resource}")

7.最后为了安全性建议在生产环境对回调进行验签再操作。有其它疑问可以互相交流


http://www.ppmy.cn/embedded/141527.html

相关文章

大模型微调论文阅读 LoRA:LOW-RANK ADAPTION OF LARGE LANGUAGE MODELS 大型语言模型的低秩自适应

论文link:https://arxiv.org/pdf/2106.09685 code:https://github.com/microsoft/LoRA LoRA:Low-Rank Adaptation of Large Language Models Abstract 自然语言处理的一个重要范例是对通用领域数据进行大规模预训练,并适应特定任…

RabbitMQ的预取值详解

RabbitMQ的预取值(Prefetch Value)是一个关键概念,它决定了消费者在从队列中获取消息时,一次性可以获取的消息数量。这一机制对于优化消息分发和消费者的负载均衡至关重要。 什么是RabbitMQ的预取值? 预取值是指消费者…

【NLP】第三章:长短期记忆网络LSTM

三、长短期记忆网络LSTM 循环神经网络的特点就是拥有"记忆",就是考虑历史信息,从历史信息中获取辅助当前的决策。 按记忆能力分:simple rnn(就是前面讲的简单rnn结构)、长短期记忆网络(LSTM)、门控循环单元(GRU)、以及双向RNN(Bi-…

【Leetcode Top 100】234. 回文链表

问题背景 给你一个单链表的头节点 h e a d head head,请你判断该链表是否为 回文链表(回文 序列是向前和向后读都相同的序列)。如果是,返回 t r u e true true;否则,返回 f a l s e false false。 数据…

jenkins 2.346.1最后一个支持java8的版本搭建

1.jenkins下载 下载地址:Index of /war-stable/2.346.1 2.部署 创建目标文件夹,移动到指定位置 创建一个启动脚本,deploy.sh #!/bin/bash set -eDATE$(date %Y%m%d%H%M) # 基础路径 BASE_PATH/opt/projects/jenkins # 服务名称。同时约定部…

设计模式——抽象工厂模式

定义与概念 抽象工厂模式是一种创建型设计模式。它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。简单来说,抽象工厂就像是一个工厂的抽象蓝图,这个蓝图定义了生产一组产品的方法,但具体怎么生产这些产…

Django 自定义路由转换器

步骤 创建自定义转换器类 必须定义 regex 属性(用于匹配参数)。必须实现 to_python 和 to_url 方法。 to_python: 将匹配的参数转换为视图函数可用的 Python 数据。to_url: 将数据转换为 URL 格式(用于反向解析)。 注册转换器 使用…

React Native 应用程序测试指南

写在前面 在软件开发中,测试是确保应用程序质量和稳定性的关键步骤。对于 React Native 应用程序来说,测试同样重要。它可以帮助你发现和修复错误,提高代码的可靠性和可维护性,并加速开发过程。本文将详细介绍如何在 React Nativ…