wizcodepl/lunar-tpay
Composer 安装命令:
composer require wizcodepl/lunar-tpay
包简介
Tpay (OpenAPI) payment driver for Lunar PHP — authorize, redirect, webhook-driven capture.
README 文档
README
lunar-tpay
Tpay (OpenAPI) payment driver for Lunar PHP.
Authorize → redirect customer to tpay → JWS-verified webhook updates the order.
Installation
composer require wizcodepl/lunar-tpay php artisan vendor:publish --tag=lunar-tpay-config
TPAY_CLIENT_ID=... TPAY_CLIENT_SECRET=... # Base URLs — omit on production (defaults to https://openapi.tpay.com / https://secure.tpay.com). # For sandbox / staging: TPAY_API_BASE_URL=https://openapi.sandbox.tpay.com TPAY_CERT_BASE_URL=https://secure.sandbox.tpay.com TPAY_RETURN_URL_SUCCESS=https://your-shop.com/order/ok TPAY_RETURN_URL_ERROR=https://your-shop.com/order/error
Get sandbox credentials at register.sandbox.tpay.com and generate Open API keys in Merchant Panel → Integration → API.
In your Lunar config/lunar.php, register the driver:
'payments' => [ 'types' => [ 'tpay' => ['driver' => 'tpay'], ], ],
The webhook route POST /tpay/notify is registered automatically. Set this URL in your tpay merchant panel.
Usage
$result = Payments::driver('tpay') ->cart($cart) ->authorize(); if ($result->success) { return redirect()->away($result->message); // tpay redirect URL }
The PaymentAuthorize.message field carries the redirect URL — that's a Lunar API quirk (the DTO doesn't have a dedicated redirectUrl field).
You can preselect a payment method (BLIK, card, specific bank) via withData():
Payments::driver('tpay') ->cart($cart) ->withData(['pay' => ['groupId' => 150]]) // 150 = BLIK ->authorize();
When omitted, tpay shows its own payment-method picker on the redirect page.
Webhook authentication — JWS x509
Tpay signs every notification with its private key (RFC 7515 detached JWS, RS256). We verify against the publicly-fetched Tpay signing certificate, chained up to the Tpay root CA. Both certificates live at:
| Production | Sandbox | |
|---|---|---|
| Signing cert | https://secure.tpay.com/x509/notifications-jws.pem |
https://secure.sandbox.tpay.com/x509/notifications-jws.pem |
| Root CA | https://secure.tpay.com/x509/tpay-jws-root.pem |
https://secure.sandbox.tpay.com/x509/tpay-jws-root.pem |
Certs are fetched once and cached for 24h. Notifications without a valid
X-JWS-Signature header are rejected with 403 SIGNATURE_INVALID. Legacy
md5sum verification is intentionally not supported — JWS is the modern,
asymmetric path with no shared secret to leak.
Testing
This package uses real sandbox tests rather than mocks. The philosophy
mirrors how Stripe, PayPal, and AWS PHP SDKs do it: real OAuth, real POST /transactions, real GET /transactions/{id} against the sandbox.
Run locally
cd packages/lunar-tpay composer install export TPAY_CLIENT_ID="your-sandbox-client-id" export TPAY_CLIENT_SECRET="your-sandbox-secret" composer test # unit + sandbox e2e composer format # Pint auto-fix composer format:check # Pint check (CI mode) composer analyse # PHPStan level 5
Without these env vars the e2e sandbox tests skip cleanly with a clear message — CI without secrets stays green.
What's covered
| Test | Tests |
|---|---|
TpayClientTest |
sandbox OAuth + create/get transaction round-trip + error handling |
TpayPaymentDriverTest |
driver registration in Lunar PaymentManager + sandbox-backed authorize() flow + meta persistence |
TpayJwsVerifierTest |
JWS verifier negative paths (empty/malformed/wrong-alg/SSRF guard) |
TpayWebhookControllerTest |
controller logic (status mapping, order lookup, response codes) — verifier swapped with a deterministic stub via the container so we don't need a real tpay signature for controller-level tests |
The full positive-path JWS verification needs a real tpay-signed payload, which only happens after a real sandbox transaction fires its webhook against a publicly-reachable URL. Validate that scenario manually after deploying to a staging URL.
Why no MockClient / VCR cassettes
For payment flows the temptation is to record API responses (à la VCR) and replay them. We chose against this because:
- Sandbox is free and reliable. tpay's OpenAPI sandbox is stable.
- Recorded fixtures drift silently when the API changes — and payment schemas change more often than people expect.
- Real sandbox calls catch credential / cert / DNS issues that mocks can't.
The downside is that running tests requires creds — solved by skip-on-empty.
What's intentionally not in v1.0
- Refunds —
refund()returnsPaymentRefund(false, …). Use the tpay merchant panel for now. - Retry queue — single attempt; failure is logged and dispatched as a
Lunar
PaymentAttemptEvent. Wrap with your own retry policy if needed. - Filament admin UI —
Order.meta.tpayis the source of truth; surface it in your panel however you prefer.
License
MIT — see LICENSE.
wizcodepl/lunar-tpay 适用场景与选型建议
wizcodepl/lunar-tpay 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 102 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 05 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「ecommerce」 「payments」 「laravel」 「polish」 「lunar」 「tpay」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 wizcodepl/lunar-tpay 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 wizcodepl/lunar-tpay 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 wizcodepl/lunar-tpay 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Nevogate Payment Gateway SDK
Dealing with payments through the Egyptian payment gateway PayMob
Librería para la gestión sencilla de pagos mediante TPV Redsys y Paypal
A PHP (and Laravel) package to interface with the Snipcart api.
Alfabank REST API integration
Customer notes for Contao Isotope eCommerce checkout.
统计信息
- 总下载量: 102
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 47
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-05-05