django实现paypal订阅记录

开发者链接 登录开发者

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


  1. 创建沙箱应用
  1. 记录 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 URL
        subscription_url = f"{PAYPAL_BASE_URL}/v1/billing/subscriptions"

        # 自定义订单号
        custom_order_id = generate_order_id()

        # 构建订阅请求的 payload
        payload = {
            "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_url
        else:
            print(f"创建订阅链接失败: {response.text}")
            return None
    except Exception as e:
        print(f"创建订阅链接时发生错误: {e}")
        return None

# 示例调用
if __name__ == "__main__":
    PLAN_ID = "P-4KL07437GC7241026M5AW2JY"  # 示例计划 ID
    approval_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.最后为了安全性建议在生产环境对回调进行验签再操作。有其它疑问可以互相交流

相关推荐
IT古董16 分钟前
【机器学习】如何使用Python的Scikit-learn库实现机器学习模型,并对数据进行预处理和特征缩放以提高模型性能?
python·机器学习·scikit-learn
cnsxjean1 小时前
SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
java·前端·spring boot·分布式·后端·中间件·架构
Want5952 小时前
Python绘制太极八卦
开发语言·python
翀哥~2 小时前
python VS c++
开发语言·c++·python
财富探秘者2 小时前
贵州茅台[600519]行情数据接口
大数据·c语言·python·算法·金融·restful
kingbal2 小时前
SpringCloud:Injection of resource dependencies failed
后端·spring·spring cloud
ℳ₯㎕ddzོꦿ࿐2 小时前
Spring Boot集成MyBatis-Plus:自定义拦截器实现动态表名切换
spring boot·后端·mybatis
逸风尊者3 小时前
开发也能看懂的大模型:RNN
java·后端·算法
菜鸟小贤贤3 小时前
python+pytest+allure利用fix实现接口关联
python·macos·自动化·pytest