simplecms/payment

支付模块

Maintainers

Package info

github.com/hackout/simplecms-payment

pkg:composer/simplecms/payment

Transparency log

Statistics

Installs: 8

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.0.0 2026-08-30 18:33 UTC

This package is auto-updated.

Last update: 2026-09-02 03:19:12 UTC


README

中文 | English

A payment package for the SimpleCMS ecosystem with a unified payment adapter layer, callback verification, refund tracking, and lifecycle events.

Highlights

  • Unified channel contract for payment adapters
  • WeChat Pay and Alipay support
  • Additional V1.5 channels: PayPal, Stripe, USDT-TRC20, USDT-ERC20, BTC, ETH
  • Standardized callback normalization and webhook verification
  • Idempotent lifecycle handling with terminal-state protection
  • Refund state synchronization and event-driven status updates
  • Configurable route prefix, currency, and channel-specific secrets

Requirements

  • PHP >= 8.1
  • SimpleCMS Framework >= 1.0
  • Composer 2

Installation

composer require simplecms/payment

If your Laravel or SimpleCMS application does not discover package providers automatically, register them manually:

// config/app.php
'providers' => [
    SimpleCMS\Payment\PaymentServiceProvider::class,
],

'aliases' => [
    'Payment' => SimpleCMS\Payment\Facades\Payment::class,
],

Configuration

The package reads channel and route settings from config/cms_payment.php. Keep secrets in the environment and never commit them to source control.

PAYMENT_CURRENCY=CNY
PAYMENT_ROUTE_PREFIX=/payment
PAYMENT_TIME_OUT=15

PAYMENT_WECHAT_APP_ID=your_wechat_app_id
PAYMENT_WECHAT_MCH_ID=your_wechat_mch_id
PAYMENT_WECHAT_SECRET_KEY=your_wechat_secret_key
PAYMENT_WECHAT_PRIVATE_KEY=/path/to/apiclient_key.pem
PAYMENT_WECHAT_CERTIFICATE=/path/to/apiclient_cert.pem

PAYMENT_ALIPAY_APPID=your_alipay_appid
PAYMENT_ALIPAY_OP_APP_ID=your_alipay_op_app_id
PAYMENT_ALIPAY_MERCHANT_KEY=your_merchant_private_key
PAYMENT_ALIPAY_PUBLIC_KEY=your_alipay_public_key

PAYMENT_PAYPAL_CLIENT_ID=your_paypal_client_id
PAYMENT_PAYPAL_CLIENT_SECRET=your_paypal_client_secret
PAYMENT_PAYPAL_WEBHOOK_ID=your_paypal_webhook_id

PAYMENT_STRIPE_API_KEY=your_stripe_secret_key
PAYMENT_STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret

PAYMENT_USDT_TRC20_RPC_URL=https://... 
PAYMENT_USDT_TRC20_ADDRESS=your_trc20_wallet
PAYMENT_USDT_ERC20_RPC_URL=https://... 
PAYMENT_USDT_ERC20_ADDRESS=your_erc20_wallet
PAYMENT_BTC_RPC_URL=https://... 
PAYMENT_BTC_ADDRESS=your_btc_wallet
PAYMENT_ETH_RPC_URL=https://... 
PAYMENT_ETH_ADDRESS=your_eth_wallet

Supported channels

use SimpleCMS\Payment\Enums\ChannelEnum;

ChannelEnum::Wechat->value;    // 1
ChannelEnum::Alipay->value;    // 2
ChannelEnum::Paypal->value;    // 3
ChannelEnum::Stripe->value;     // 4
ChannelEnum::USDTTRC20->value; // 5
ChannelEnum::USDTERC20->value; // 6
ChannelEnum::BTC->value;        // 7
ChannelEnum::ETH->value;        // 8

Model requirement

Your order model should implement the HasPayment contract:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use SimpleCMS\Payment\HasPayment;

class Order extends Model implements HasPayment
{
    public function payment(): MorphOne
    {
        return $this->morphOne(\SimpleCMS\Payment\Models\Payment::class, 'order');
    }

    public function getOrderKey(): string
    {
        return 'order_no';
    }
}

Create a payment

use SimpleCMS\Payment\Enums\ChannelEnum;
use SimpleCMS\Payment\Facades\Payment;

$result = Payment::create($order, 99.99, ChannelEnum::Wechat->value, 'Test order');

V2 operational flow

The operational V2 flow is integrated into the main payment facade so it is used as part of the same package runtime instead of as a separate standalone API.

use SimpleCMS\Payment\Facades\Payment;

$transfer = Payment::transferCreate([
    'order_no' => 'TXN-1001',
    'amount' => 199.99,
    'channel' => 'wechat',
]);

$approval = Payment::approvalRun('withdrawal', [
    'amount' => 15000,
    'channel' => 'wechat',
]);

$reconciliation = Payment::reconciliationRun('wechat', '2024-06-30');

Host app integration example

In a Laravel or SimpleCMS application, register the package provider and then use the main payment facade for both the original payment flows and the V2 operational flows from the same runtime:

// config/app.php
'providers' => [
    SimpleCMS\Payment\PaymentServiceProvider::class,
],

'aliases' => [
    'Payment' => SimpleCMS\Payment\Facades\Payment::class,
],
use SimpleCMS\Payment\Facades\Payment;

public function dispatchWithdrawal(): array
{
    return Payment::transferCreate([
        'order_no' => 'WITHDRAW-2026-001',
        'amount' => 2500,
        'channel' => 'wechat',
        'direction' => 'out',
    ]);
}

The same runtime can be used for operational tasks like risk checks, settlement runs, and reconciliation at scheduled intervals.

Callback and verification

The callback service standardizes provider payloads and verifies signatures before changing payment state.

  • Stripe: verifies the Stripe-Signature header against the webhook secret
  • PayPal: validates transmission metadata and webhook identity
  • Replay and terminal-state updates are blocked to prevent stale callback overwrites

Events

use SimpleCMS\Payment\Models\Payment;

Event::listen('plugin.payment.created', function (Payment $payment) {
    // created
});

Event::listen('plugin.payment.pending', function (Payment $payment) {
    // awaiting payment
});

Event::listen('plugin.payment.paid', function (Payment $payment) {
    // payment succeeded
});

Event::listen('plugin.payment.refunding', function (Payment $payment) {
    // refund in progress
});

Event::listen('plugin.payment.refunded', function (Payment $payment) {
    // refund succeeded
});

Event::listen('plugin.payment.close', function (Payment $payment) {
    // payment closed
});

Notes

  • Keep secrets in .env or your deployment secret manager.
  • Do not commit certificate files, keys, or webhook secrets.
  • Ensure your application exposes payment callback routes and handles provider webhook headers correctly.
  • This package is designed for Laravel/SimpleCMS integration and uses an adapter-based architecture for provider expansion.

License

MIT