支付
学习如何在 MinuteShip 中设置和使用支付
MinuteShip 支持多种支付提供商,您可以根据需要选择合适的支付方案。
支付提供商
共用支付流程
三个支付提供商共用相同的应用路由和已认证的服务端函数:
/pricing发起结账。/settings/payment等待当前结账创建的支付记录。/settings/billing显示有效计划,并打开支付提供商的客户门户。
Stripe 使用 session_id 标识订单;Creem 和 Waffo 则通过 request_id 或 checkout_id 传回服务端生成的订单引用。MinuteShip 会同时按该引用和当前登录用户查询,因此旧的已支付订单不会误判为本次结账成功。
结账成功、取消、回调和客户门户返回地址必须是根路径相对地址,或使用 VITE_BASE_URL 配置的完全相同来源。外部来源、协议相对地址、协议变更和子域名都会被拒绝。
自定义支付提供商
MinuteShip 支持扩展新的支付提供商:
- 在
src/payment/provider目录中创建新的文件 - 从
types.ts实现PaymentProvider接口 - 在
index.ts中的providerRegistry注册新的提供商
接口还包含两个可选的行为标志:
requiresCustomerId默认为true。只有当支付提供商使用共享门户、且没有独立客户记录时,才设为false。hostsPostCheckoutPage默认为false,即采用 Stripe 的{CHECKOUT_SESSION_ID}流程。当支付提供商托管自己的确认页面,并通过 metadata 和 Webhook 返回订单引用时,将其设为true。
新的支付服务提供商的示例实现:
src/payment/provider/my-provider.ts
import type {
PaymentProvider,
CreateCheckoutParams,
CheckoutResult,
CreatePortalParams,
PortalResult,
} from '../types';
export class MyProvider implements PaymentProvider {
readonly requiresCustomerId = true;
readonly hostsPostCheckoutPage = false;
getProviderName(): string {
return 'my-provider';
}
public async createCheckout(params: CreateCheckoutParams): Promise<CheckoutResult> {
// Create checkout session implementation
}
public async createCustomerPortal(params: CreatePortalParams): Promise<PortalResult> {
// Create customer portal implementation
}
public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
// Handle webhook events implementation
}
}
然后在 index.ts 中的 providerRegistry 注册新的提供商:
src/payment/index.ts
import { MyProvider } from './provider/my-provider';
const providerRegistry: Record<PaymentProviderName, ProviderFactory> = {
stripe: () => new StripeProvider(),
creem: () => new CreemProvider(),
waffo: () => new WaffoProvider(),
'my-provider': () => new MyProvider(),
};