IHP框架中的Stripe支付集成指南

IHP框架中的Stripe支付集成指南

前言

在现代Web应用中,支付功能是许多SaaS产品的核心需求。本文将详细介绍如何在IHP框架中集成Stripe支付系统,实现完整的订阅式支付流程。

准备工作

环境配置

首先需要在项目中添加ihp-stripe依赖。修改default.nix文件:

let
    haskellDeps = p: with p; [
        ihp-stripe
        # 其他依赖...
    ];

然后在Config/Config.hs中添加Stripe配置模块:

import IHP.Stripe.Config

config :: ConfigBuilder
config = do
    -- 其他配置...
    initStripe

API密钥设置

在启动脚本中添加Stripe API密钥:

export STRIPE_WEBHOOK_SECRET_KEY="your_webhook_secret"
export STRIPE_PUBLIC_KEY="your_public_key"
export STRIPE_SECRET_KEY="your_secret_key"

建议在开发阶段使用测试环境的API密钥。

订阅系统实现

数据模型设计

  1. 计划表(plans):存储不同的订阅计划
CREATE TABLE plans (
    id UUID PRIMARY KEY,
    name TEXT NOT NULL,
    stripe_price_id TEXT NOT NULL
);
  1. 订阅表(subscriptions):记录用户订阅信息
CREATE TABLE subscriptions (
    id UUID PRIMARY KEY,
    user_id UUID REFERENCES users(id),
    starts_at TIMESTAMP WITH TIME ZONE,
    ends_at TIMESTAMP WITH TIME ZONE,
    is_active BOOLEAN,
    stripe_subscription_id TEXT,
    plan_id UUID REFERENCES plans(id),
    quantity INT
);
  1. 用户表扩展:添加支付相关字段
ALTER TABLE users ADD COLUMN stripe_customer_id TEXT;
ALTER TABLE users ADD COLUMN plan_id UUID REFERENCES plans(id);
ALTER TABLE users ADD COLUMN subscription_id UUID REFERENCES subscriptions(id);

支付流程实现

  1. 创建Checkout控制器
data CheckoutSessionsController
    = CheckoutSuccessAction
    | CheckoutCancelAction
    | CreateCheckoutSessionAction
  1. 支付会话创建
action CreateCheckoutSessionAction = do
    plan <- query @Plan |> fetchOne
    session <- Stripe.send CreateCheckoutSession
        { successUrl = urlTo CheckoutSuccessAction
        , cancelUrl = urlTo CheckoutCancelAction
        , mode = "subscription"
        , customer = currentUser.stripeCustomerId
        , lineItem = LineItem plan.stripePriceId 1
        }
    redirectToUrl session.url
  1. 支付结果处理
action CheckoutSuccessAction = do
    setSuccessMessage "订阅成功!"
    redirectToPath "/"

action CheckoutCancelAction = do
    setErrorMessage "支付已取消"
    redirectToPath "/"

Webhook集成

创建Webhook控制器处理Stripe事件:

instance StripeEventController where
    on CheckoutSessionCompleted { subscriptionId, customer, metadata } = do
        -- 处理支付成功事件
        user <- fetch userId
        subscription <- newRecord @Subscription
            |> set #userId user.id
            |> set #stripeSubscriptionId subscriptionId
            |> createRecord
        pure ()

进阶功能实现

账单管理门户

允许用户自主管理订阅:

action OpenBillingPortalAction = do
    portal <- Stripe.send CreateBillingPortalSession
        { customer = currentUser.stripeCustomerId
        , returnUrl = urlTo StartpageAction
        }
    redirectToUrl portal.url

发票管理

  1. 发票表设计
CREATE TABLE invoices (
    id UUID PRIMARY KEY,
    subscription_id UUID REFERENCES subscriptions(id),
    stripe_invoice_id TEXT,
    invoice_url TEXT,
    invoice_pdf TEXT,
    total INT,
    currency TEXT
);
  1. 发票Webhook处理
on InvoiceFinalized { subscriptionId, invoiceUrl } = do
    subscription <- fetchBy stripeSubscriptionId subscriptionId
    invoice <- newRecord @Invoice
        |> set #subscriptionId subscription.id
        |> set #invoiceUrl invoiceUrl
        |> createRecord
    pure ()

最佳实践建议

  1. 测试策略

    • 始终在开发环境使用Stripe测试模式
    • 模拟各种支付场景(成功、失败、退款等)
  2. 安全考虑

    • 妥善保管API密钥
    • 验证Webhook签名
    • 实现CSRF保护
  3. 用户体验优化

    • 提供清晰的支付状态反馈
    • 设计友好的错误处理流程
    • 实现本地化的价格显示

常见问题排查

  1. Webhook未触发

    • 检查Stripe CLI配置
    • 验证端点URL是否正确
    • 确认事件订阅设置
  2. 支付会话问题

    • 检查价格ID格式
    • 验证客户ID有效性
    • 确认支付方式配置
  3. 数据库同步延迟

    • 实现适当的重试机制
    • 添加日志记录关键步骤
    • 考虑使用后台任务处理复杂操作

通过本文的指导,开发者可以在IHP框架中快速实现完整的Stripe支付集成,为应用添加专业的订阅支付功能。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎崧孟Lolita

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值