Repository navigation
feat(sdks): TS auto-retry with backoff, Go payment links + WaitForPayment and examples, Python mock-server test suite - #1276
Open
JosephOladele wants to merge 4 commits into
Conversation
… POST retries - maxRetries option (default 2; retries kept as a deprecated alias) - per-attempt timeout via AbortSignal.timeout (default 30s), surfaced as FluxaPayError 408 REQUEST_TIMEOUT - configurable exponential backoff with full jitter - Retry-After (seconds or HTTP date) honoured on 429; waits longer than retryMaxDelayMs surface the error instead - POST/PATCH only retried when an Idempotency-Key is sent (payments.create options, refunds idempotency_key) - unit tests for retry counts, statuses, Retry-After and timeouts Closes MetroLogic#1266
- CreatePaymentLink and PaymentLinks.Create/Get/List with json-tagged request/response structs and client-side validation (ErrInvalidParams) - WaitForPayment with immediate first poll, exponential backoff, poll timeout and context cancellation; retries transient errors - typed errors: PaymentStatusError (ErrPaymentNotSuccessful) and WaitTimeoutError (unwraps to the context error) - httptest coverage for success, error and timeout paths Closes MetroLogic#1265
- examples/checkout_flow: create a payment and wait for completion - examples/webhook_server: net/http server verifying webhook signatures - examples/payment_links: create and list payment links - examples/README.md with env var setup, run steps and a Gin snippet - Go SDK CI job that vets, builds the examples and runs tests Closes MetroLogic#1268
- pytest suite covering merchants, payments, payment links, refunds and webhooks (sync and async) with canonical response fixtures - 200/400/401/404/500 matrix plus 403/410/422/429/503 handling - typed exceptions (BadRequestError, AuthenticationError, NotFoundError, RateLimitError, ServerError, ...) all subclassing FluxaPayError - payment_links and merchants resources, custom headers and timeout client options, refund Idempotency-Key header - GitHub Actions workflow running pytest on Python SDK changes Closes MetroLogic#1267
|
@JosephOladele Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR covers four SDK issues. Each one has its own commit.
Closes #1265
Closes #1266
Closes #1267
Closes #1268
#1266: TypeScript SDK auto-retry with exponential backoff
maxRetries(default 2; the oldretriesoption still works as a deprecated alias),timeout(per attempt, default 30s,0disables),retryInitialDelayMsandretryMaxDelayMs.Retry-Afterasks, whether it's given in seconds or as an HTTP date. If the wait would be longer thanretryMaxDelayMs, it returns the 429 instead of hanging.Idempotency-Keyis sent.payments.create(params, { idempotencyKey })andrefunds.create({ idempotency_key })now send that header. A POST to create a payment without a key is never retried, so a retry can't double-charge.AbortSignal.timeout. If the last attempt times out, the SDK throwsFluxaPayErrorwith status 408 and codeREQUEST_TIMEOUT.sdk.test.ts: default and configured retry counts, each retryable status, no retry on 500, POST with and without an idempotency key, the Retry-After cap, Retry-After as an HTTP date, the backoff schedule, timeouts, andtimeout: 0.#1265: Go SDK payment link and polling helpers
client.CreatePaymentLink(ctx, *CreatePaymentLinkParams) (*PaymentLink, error), plusclient.PaymentLinks.Create/Get/List. Request and response structs have json tags for every field. Parameters are validated client-side first (errors wrapErrInvalidParams), so bad input never makes a request.client.WaitForPayment(ctx, paymentID, opts ...PollOption) (*Payment, error), also available asclient.Payments.WaitForPayment:WithPollInterval,WithMaxPollInterval,WithPollBackoff,WithPollTimeout,WithSuccessStatuses,WithFailureStatuses,WithOnPoll.*PaymentStatusError, which matcheserrors.Is(err, ErrPaymentNotSuccessful). A timeout or cancellation returns*WaitTimeoutError, which unwraps to the context error and records the last status seen.WithPollTimeout, cancellation, transient-error retries, permanent errors, validation and the backoff math.#1268: Go SDK examples and quickstart
examples/checkout_flow: creates a payment, printscheckout_url, waits withWaitForPayment, and exits with a distinct code for success, failure, or timeout/Ctrl+C.examples/webhook_server: anet/httpserver. It reads the raw body with a size limit, verifies the signature and the 300s timestamp window, dispatches on event type, and shuts down gracefully.examples/payment_links: creates a fixed-amount or open-amount link and lists active links.examples/README.md: setting environment variables on macOS/Linux and PowerShell, run steps for each example, a Gin snippet, and an error-handling cheat sheet. The SDK README is updated too.go.modgets no new dependencies.go-sdk-ci.ymlrunsgo vet, builds the examples, and runsgo test -raceon Go SDK changes.#1267: Python SDK mock server tests
tests/conftest.pyholds canonical response fixtures (payment, payment link, merchant, refund, error bodies) and a respx router fixture.tests/test_mock_server.pycovers:BadRequestError,AuthenticationError,PermissionDeniedError,NotFoundError,ConflictError,RateLimitError(withretry_after) andServerError, all subclassingFluxaPayError; field errors are exposed on.errorsclient.payment_linksandclient.merchantsresourcesheaders=andtimeout=client options; custom headers can't overrideAuthorizationidempotency_keyas theIdempotency-Keyheaderpython-sdk-ci.ymlruns pytest on Python 3.9–3.12 for PRs that change the Python SDK.All new and changed SDK code is covered by tests, and the existing tests are unchanged.