Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Coupon Wechat Mini Program Bundle Laravel Package

tourze/coupon-wechat-mini-program-bundle

Tourze Coupon WeChat Mini Program Bundle adds WeChat Mini Program coupon support to Symfony applications. It provides bundle-level integration and reusable services for coupon-related backend flows, giving Tourze-based projects a framework-native starting point for mini program coupon features.

View on GitHub
Deep Wiki
Context7

Getting Started

What this is. tourze/coupon-wechat-mini-program-bundle is an early-stage (0.0.x) wrapper around the WeChat Mini Program coupon APIs — stock/issuance/redemption calls against api.weixin.qq.com. Note the -bundle suffix: this comes from the tourze family of Symfony bundles. There is no Laravel service provider, no config/coupon-wechat.php to publish, no facade. You consume it as a plain library and wire it into Laravel's container yourself.

First 15 minutes.

  1. composer require tourze/coupon-wechat-mini-program-bundle:0.0.2 (pin exactly — see Gotchas).
  2. Read composer.json first, not the README. Whatever it requires for Mini Program auth (tourze/wechat-mini-program-bundle or equivalent) is the real integration surface — that's where access_token handling, appid/secret config, and the HTTP client live. This package is likely a thin layer on top.
  3. Open src/ and find the bundle class and the DI extension/Configuration class. That tree tells you every option the services accept. Then find the service classes that build the coupon requests.
  4. Skip the docs; at 0.0.x the source is the documentation. Budget an hour to read it end to end.

Prerequisites to line up before you write code: an authenticated Mini Program (appid + secret), a shared server-side token cache (Redis), outbound HTTPS to api.weixin.qq.com, and — critically — a Mini Program account whose category actually qualifies for coupon APIs.

First use case: post-checkout issuance. After an order is paid, issue a stock coupon to the buyer's openid. It's the smallest slice that exercises auth, the token cache, request serialization, and WeChat's error semantics all at once. Everything else (listing user coupons, redemption sync) builds on the same plumbing.

Implementation Patterns

Register the pieces in a service provider. Build the underlying Mini Program client as a singleton in AppServiceProvider, then construct the coupon service with it. Treat the bundle's classes as constructor-injected collaborators, not as framework magic.

Wrap it in your own service. The package's method signatures and return shapes are not stable at 0.0.x. Put a CouponIssuer class in app/ with typed methods (issueStockCoupon(string $openid, string $stockId): IssuedCoupon) and your own DTOs. One file to change when the package shifts, and your domain code never sees WeChat's field names.

Issue from a queued job, with idempotency. WeChat's send-coupon call is not idempotent — a timeout followed by a naive retry gives the user two coupons or an ambiguous state. Key the job on your order ID, record an issuance row before the call with a pending status, and reconcile on retry.

Own the token lifecycle once. Whoever fetches access_token must be the only fetcher. Cache it in Redis with the returned TTL minus a safety margin, and refresh behind a lock. If you already run another WeChat SDK in the same app, consolidate — two token managers invalidate each other's tokens and produce maddening intermittent 40001 failures.

Map WeChat error codes to domain exceptions at the boundary. Distinguish retryable (-1 system busy, 45009 rate limit) from terminal (40001 bad credential, stock exhausted, unqualified account). Only the retryable class goes back on the queue.

Keep a local mirror table. WeChat is the authority for redemption state, but never render a user's coupon list from a live API call. Maintain coupons / coupon_issuances tables and reconcile with a scheduled sync job.

Handle the message push. Coupon lifecycle events arrive as signed pushes to your configured server URL. Verify msg_signature / timestamp / nonce before trusting the payload, then dispatch an internal event.

Test against your wrapper, not the package. Fake your CouponIssuer interface in feature tests; use Http::fake() at the Guzzle layer when you want to test the wrapper itself. Never let the test suite hit api.weixin.qq.com.

Gotchas and Tips

0.0.2 shipped with no changelog — the release notes are just a compare link. Diff 0.0.1...0.0.2 on GitHub (or in vendor/) before you upgrade, and pin exact versions with composer require ...:0.0.2. At 0.0.x, a patch bump can rename a class.

Symfony config doesn't exist in Laravel. You will not find a config tree loader. The bundle's Configuration class documents the available options, but you must pass them to constructors yourself. Don't go looking for a publishable config file that isn't there.

Laravel auto-discovery will not find it. No extra.laravel block, no provider. Everything is manual binding.

HTTP 200 does not mean success. WeChat returns 200 OK with a non-zero errcode in the body. Any error handling keyed on status codes will silently swallow every failure — including "coupon stock exhausted," which you'll discover from a support ticket rather than a log line.

Log the raw request and response bodies. When a call fails, the WeChat error message is the only useful artifact. Redact access_token and openid if your logs are shipped anywhere.

Qualification gates everything. Coupon APIs are restricted by Mini Program category and account status. If your test account isn't qualified, you'll get confusing permission errors and burn a day blaming the package. Confirm qualification before you evaluate the code.

Rate limits are per-account, not per-endpoint. Bulk issuance jobs need a token bucket shared across all WeChat calls in the app, not just coupons.

Extension points: swap the HTTP client binding for a retrying/mocking client; decorate the service class rather than forking it; and if the package's service is final or the API is too thin, drop to the underlying Mini Program client and hand-roll the two or three endpoint calls — at this maturity that's a legitimate outcome, not a failure.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect