Library / SDK
yansongda/pay avatar
yansongda/pay

yansongda/pay: A PHP Payment SDK for Alipay, WeChat and Douyin

可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了

5,371 stars1,053 forksPHPMIT

At a glance

What is it?
A Composer package that wraps Alipay, WeChat, Douyin, Unipay, Jiangsu Bank, Tonglian and BestPay behind one plugin-based API, with Laravel and Hyperf integrations kept in separate repositories.
Who is it for?
Adopt yansongda/pay if you run a PHP application that has to talk to more than one Chinese payment provider and you want a single config array and one callback method per gateway. Skip it if you need only one gateway, since the abstraction adds a layer you will not use, or if you cannot accept a beta release line for production.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem yansongda/pay was written to remove

The README opens with a blunt account of why the project exists: after building Alipay and WeChat integrations several times, the author looked for an existing library and found none that felt right, either hard to understand or messy in file structure. That is the origin story, and it explains the design priorities. The target user is a PHP developer who has to wire up Chinese payment gateways and does not want to hand-assemble JSON for WeChat and XML for Alipay each time a new endpoint is needed.

The scope is broader than the two best-known providers. The README lists Alipay, WeChat, Douyin, Unipay, Jiangsu Bank (e-Rong Pay), Tonglian Pay and BestPay (翼支付), each with its own list of supported methods. Alipay covers web, wap, app, barcode, QR, account transfer and mini program payments. WeChat covers official account, mini program, H5, QR, app and barcode. Douyin lists mini program payment, order query, CPS query, refund, refund review and callbacks. Unipay lists wap, web, barcode and QR. Jiangsu Bank is described as aggregate QR payment across WeChat, Alipay, Unipay and e-Rong. Tonglian adds unified payment, passive and active scan, query, confirm query, refund, reversal and close order. BestPay adds PC cashier, mobile cashier, aggregate QR, order query, refund, close order and certificate-verified callbacks.

That list is the real argument for the package. A single Composer dependency that speaks to seven providers is a different proposition from a wrapper around one.

How the plugin mechanism and gateway abstraction fit together

The README states that v3 redesigned the underlying architecture relative to v2, and that the project is 100 percent compatible with Alipay, WeChat and Unipay functionality, including service provider features, provided the right plugin is pulled in. The listed features include multi-tenant support, Swoole support, a plugin mechanism, an event system, automatic retrieval of WeChat public certificates, and conformance with PSR-2, PSR-3, PSR-4, PSR-7, PSR-11, PSR-14 and PSR-18.

The PSR list matters more than it looks. PSR-7 and PSR-18 mean the HTTP layer is not welded to one client, and the README's config example exposes a Guzzle options block, so request behaviour such as timeouts is tunable. PSR-11 and PSR-14 mean container and event integration are part of the contract rather than an afterthought, which is what makes the separate Laravel and Hyperf packages possible.

The data flow visible in the README is consistent across gateways. You build a config array, hand it to Pay::config(), then call a gateway accessor such as Pay::alipay() and a method such as web() with an associative array of business parameters. For inbound traffic the same accessor exposes callback(), which performs signature verification and returns a data object whose properties are read directly, for example $data->out_trade_no and $data->trade_no. The README's comment on the return callback is short and to the point: verification is that simple. The abstraction is doing real work there, because the signature rules differ between providers and the caller does not see them.

Installing yansongda/pay and taking a first Alipay payment

The README gives one install command, pinned to the 3.7 line:

bash
composer require yansongda/pay:~3.7.0 -vvv

The -vvv flag raises Composer's verbosity, which is useful when a certificate path or extension problem interrupts resolution.

Configuration is a plain PHP array. The Alipay block requires an app_id, the application private key, and three certificate paths: the application public certificate, the Alipay public certificate, and the Alipay root certificate. Optional keys include return_url, notify_url, app_auth_token, service_provider_id, and mode, which accepts Pay::MODE_NORMAL, Pay::MODE_SANDBOX or Pay::MODE_SERVICE. A logger block and an http block with timeout and connect_timeout sit alongside the gateway config.

php
Pay::config($this->config);

$result = Pay::alipay()->web([
    'out_trade_no' => ''.time(),
    'total_amount' => '0.01',
    'subject' => 'yansongda 测试 - 1',
]);

That call returns the result the documentation shows being returned straight from the controller, which for a web payment is the form or redirect payload the browser needs.

For the asynchronous side, the README uses the same accessor with callback(), wrapped in a try/catch:

php
$data = Pay::alipay()->callback();

// 订单号:$data->out_trade_no
// 支付宝交易号:$data->trade_no
// 订单总金额:$data->total_amount

return Pay::alipay()->success();

The documentation is explicit that callback() only handles verification. The surrounding comments list five checks the merchant still owns: confirm out_trade_no matches an order in your system, confirm total_amount matches the order amount, confirm seller_id or seller_email belongs to that order, confirm app_id is your own, and then run your business logic. It also notes that Alipay treats a payment as successful only when trade_status is TRADE_SUCCESS or TRADE_FINISHED. Reading that list is the difference between a working integration and one that credits orders it should not.

Where the abstraction stops helping

The README is honest that callback() is verification only, and that is the first real limitation: every business rule about what a notification means stays with you. The five checks above are not optional, and a library cannot perform them because it has no view of your order table.

A second constraint is the release line. The three most recent releases listed are v3.8.0-beta.6, v3.8.0-beta.5 and v3.8.0-beta.4, dated 2026-09-11, 2026-09-04 and 2026-08-24. The README's own install command points at ~3.7.0, not at 3.8. Anyone who runs composer require yansongda/pay without a constraint may resolve to a beta, and beta lines move. Pin the version you have validated.

A third is framework fit. Laravel, Hyperf and Yii users are pointed at separate repositories, yansongda/laravel-pay, yansongda/hyperf-pay and guanguans/yii-pay. Those packages carry their own release cycles, so a framework integration can lag the core SDK, and the README does not describe how those packages track core versions.

Finally, the README does not document rollback or migration steps between major versions. It says only that v3 differs substantially from v2 at the foundation. If you have a v2 codebase, treat the upgrade as a rewrite of your payment layer and read the documentation site rather than assuming the call sites carry over.

How it differs from IJPay and other Java-side options

People searching around this project often land on IJPay, and the comparison is worth making explicit because the two are not interchangeable. IJPay is a Java payment library; yansongda/pay is PHP, distributed through Packagist, and its integration story is built on Composer, PSR interfaces and framework service providers. If your service is a JVM application, yansongda/pay is simply the wrong tool, and no amount of API similarity changes that.

The more useful comparison is within PHP, against writing the integrations yourself or using a single-provider SDK. A provider-specific SDK usually models one gateway closely and gives you its full parameter surface, but adding a second provider means a second dependency, a second config format, and a second callback verification path. yansongda/pay trades some of that per-provider specificity for a uniform shape: one config array, one accessor per gateway, one callback method name. The cost is a layer of indirection between you and the provider's raw API, and the benefit is that switching or adding a gateway does not change how your controller is written.

Daxpay also appears in related searches. The README says nothing about it, so any comparison here would be guesswork, and the honest position is that this article cannot make one.

Maintenance, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-11, with a release tagged the same day. That is recent activity by any measure. The project is licensed under MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive arrangement, but it is not legal advice: if you redistribute the SDK inside a product, read the LICENSE file in the repository root and get your own review.

The upgrade cost is the part worth budgeting for. The README states that v3 redesigned the foundation relative to v2, so a v2 to v3 move is not a patch. Within v3, the beta releases suggest the 3.8 line is still settling, and the README's install command deliberately targets 3.7. A practical approach is to stay on a fixed 3.7.x release until 3.8.0 is stable, then move deliberately. The repository also ships a docs/ directory, an AGENTS.md file, a CHANGELOG.md, and a web/ directory, so release notes and documentation live in the tree rather than only on the site.

Editorial conclusion

Adopt yansongda/pay if you run a PHP application that has to talk to more than one Chinese payment provider and you want a single config array and one callback method per gateway. Skip it if you need only one gateway, since the abstraction adds a layer you will not use, or if you cannot accept a beta release line for production. Before adopting, read the version planning page, confirm which branch your framework integration targets, and check whether the gateway you need is listed under the supported payment methods.

Frequently asked questions

Which payment providers does yansongda/pay support?

The README lists Alipay, WeChat, Douyin, Unipay, Jiangsu Bank (e-Rong Pay), Tonglian Pay and BestPay, each with its own set of supported methods such as web, wap, app, QR, barcode, refund and order query. The project states it is 100 percent compatible with Alipay, WeChat and Unipay functionality, including service provider features, through its plugin mechanism.

How do I install yansongda/pay with Composer?

The README gives the command composer require yansongda/pay:~3.7.0 -vvv, which pins the package to the 3.7 line. The most recent releases listed are v3.8.0 beta versions, so the README's own constraint avoids resolving to a beta.

Does yansongda/pay work with Laravel and Hyperf?

The README points Laravel users to yansongda/laravel-pay, Hyperf users to yansongda/hyperf-pay, and Yii users to guanguans/yii-pay. Those are separate repositories, so their release timing is independent of the core SDK.

Does yansongda/pay verify payment callbacks for me?

Yes, signature verification is handled by the callback() method, which the README shows returning a data object with properties such as out_trade_no, trade_no and total_amount. The README is explicit that this is verification only, and that you must still check the order number, amount, seller identity and app_id in your own code.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. yansongda/pay on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yansongda-pay.svg)](https://hysenlabs.com/projects/yansongda-pay)