Skip to content

Latest commit

 

History

History
176 lines (133 loc) · 6.01 KB

File metadata and controls

176 lines (133 loc) · 6.01 KB

Payment

Crates.io License: MIT

A unified payment SDK for Rust. Integrate Alipay, WeChat Pay, Stripe, and more through a single, consistent API.

Features

  • Unified InterfacePaymentProvider trait abstracts away provider-specific APIs. Write once, switch anytime.
  • Modular by Design — Each payment provider is gated behind a Cargo feature. Only compile what you need.
  • Type-Safe — Domain types (Amount, Currency, PaymentOrder, etc.) with full serde support.
  • Extensible — Adding a new provider requires only a trait implementation + a feature flag; core remains untouched.
  • Async First — Built on async-trait + reqwest. Runtime-agnostic (works with tokio).

Supported Providers

Provider Feature Flag Status Description
Alipay (支付宝) alipay 📋 QR code, H5, App payment
WeChat Pay (微信支付) wechat 📋 JSAPI, Native, H5, App
Stripe stripe 📋 Payment Intents, Webhooks

Current Status — Phase 1 Complete

The foundational layer is implemented and fully tested (57 tests, 0 clippy warnings):

Layer Module Description
utils/ crypto.rs HMAC-SHA256, MD5, SHA256, Base64, sign string builder
utils/ http.rs HttpClient with retry, timeout, proxy support
utils/ xml.rs XML serialize / deserialize via quick-xml
core/ error.rs PaymentError enum (9 variants) + PaymentResult<T>
core/ types.rs Amount, Currency, PaymentOrder, PaymentResponse, PaymentCredential, RefundOrder, etc.
core/ config.rs ProviderConfig trait (Send + Sync, object-safe)
core/ traits.rs PaymentProvider + SignablePayment async traits

Roadmap

  • Phase 1 — Core abstractions & utilities
  • Phase 2 — Alipay provider
  • Phase 3 — WeChat Pay provider
  • Phase 4 — Stripe provider
  • Phase 5 — Polish: logging, mock provider, CI/CD, docs

Installation

Add payment to your Cargo.toml, selecting the providers you need:

[dependencies]
payment = { version = "0.0.1", features = ["alipay"] }

Available feature flags:

Flag Description
alipay Alipay provider
wechat WeChat Pay provider
stripe Stripe provider
all Enable all providers
domestic alipay + wechat
international stripe

No features are enabled by default.

Usage

Provider implementations are coming in Phase 2–4. The API surface is already defined.

use payment::{
    Amount, Currency, PaymentOrder,
    PaymentProvider, PaymentError,
};

// When providers are implemented:
// use payment::AlipayProvider;

async fn pay() -> Result<(), PaymentError> {
    // let provider = AlipayProvider::new(config)?;

    let order = PaymentOrder {
        out_trade_no: "ORDER_20240501_001".into(),
        amount: Amount {
            total: 100,             // in cents (1.00 CNY)
            currency: Currency::CNY,
        },
        subject: "Test Item".into(),
        body: None,
        expire_time: None,
        attach: None,
        extra: None,
    };

    // let response = provider.create_order(order).await?;
    // println!("Payment credential: {:?}", response.credential);

    Ok(())
}

Switching Providers at Runtime

use payment::{PaymentProvider};

fn get_provider(channel: &str) -> Box<dyn PaymentProvider> {
    match channel {
        // "alipay" => Box::new(AlipayProvider::new(config).unwrap()),
        // "wechat" => Box::new(WechatProvider::new(config).unwrap()),
        // "stripe" => Box::new(StripeProvider::new(config).unwrap()),
        _ => unimplemented!(),
    }
}

Project Structure

src/
├── lib.rs                   # Top-level: feature gate + re-exports
├── utils/                   # Shared utilities (always compiled)
│   ├── crypto.rs            # Signing, hashing, signature string builder
│   ├── http.rs              # HTTP client with retry & timeout
│   └── xml.rs               # XML serialization
└── core/                    # Core abstractions (always compiled)
    ├── error.rs             # Unified error types
    ├── types.rs             # Domain data types
    ├── config.rs            # ProviderConfig trait
    └── traits.rs            # PaymentProvider + SignablePayment traits

  # Planned (Phase 2–4):
  # └── providers/
  #     ├── alipay/           # Alipay provider
  #     ├── wechat/           # WeChat Pay provider
  #     └── stripe/           # Stripe provider

Development

Prerequisites

  • Rust 1.75+ (2021 edition)
  • Cargo

Running Tests

# All tests
cargo test

# Specific module
cargo test utils::crypto
cargo test core::types

# Clippy
cargo clippy -- -D warnings

Adding a New Provider

  1. Create src/providers/<name>/ with mod.rs, client.rs, config.rs, types.rs
  2. Implement PaymentProvider trait for your provider struct
  3. Add #[cfg(feature = "...")] gate in src/providers/mod.rs
  4. Add re-export in src/lib.rs
  5. Add feature flag and optional dependencies in Cargo.toml

License

MIT © Echo