Skip to main content

Best practices

These patterns mirror how production payment backends are usually structured: secrets on the server, integer money, idempotent callbacks, and clear error semantics.
These recommendations help you build resilient, maintainable payment integrations.

1. Keep API credentials server-side only

Never expose clientSecret or backend API credentials in frontend bundles.
  • Initialize the SDK in backend services only
  • Read credentials from environment variables or a secrets manager
  • Rotate credentials on a regular schedule

2. Use unique order numbers

Treat order_number as a unique business identifier.
  • Include your internal order ID
  • Avoid random values that cannot be traced back to your systems
  • Keep a stable mapping between your order and GoPay payment ID

3. Store amounts in minor units

GoPay amounts are sent in minor currency units.
  • 10000 CZK minor units = 100.00 CZK
  • Avoid floating point math for payment totals
  • Prefer integer-safe calculations

4. Handle asynchronous payment completion

Creating a payment and redirecting users is only one part of the flow.
  • Users can abandon checkout
  • Browser return callbacks can fail
  • Final status should be confirmed by server-side logic
Recommended approach:
  1. Create payment
  2. Redirect user to gw_url
  3. Process notification callback on your backend
  4. Verify payment state using getPayment
  5. Mark order as paid only after terminal success state

5. Distinguish retryable vs non-retryable failures

Use GoPayApiError metadata:
  • status for HTTP class
  • errors for field-level details
  • endpoint for diagnostics and logs
Typical strategy:
  • Retry transient infrastructure failures (timeouts, 5xx) with backoff
  • Do not blindly retry validation/business rule errors (4xx)

6. Reuse client instances

Create a long-lived client instance per merchant configuration instead of per request. Why:
  • Better token cache reuse
  • Lower token endpoint traffic
  • Lower latency for regular operations

7. Tune timeout values by operation type

Use timeoutMs based on network and infrastructure behavior:
  • Too low: avoidable failures during network jitter
  • Too high: slow error feedback and stuck request resources
Start with default and adjust based on observed latency/error profiles.

8. Use custom transport for observability

Inject a custom HttpTransport to add:
  • request tracing IDs
  • metrics (latency, status codes)
  • structured logs
  • proxy / internal networking behavior
See Extensibility reference.

9. Add integration tests around your business flow

The library’s own tests cover the SDK in isolation; your application should also test:
  • order creation -> payment creation mapping
  • callback handling and idempotency
  • order state transitions in your own data model

10. Keep the SDK version up to date

  • Pin gopay-sdk to an explicit semver range in your app’s package.json (avoid unbounded * in production).
  • When upgrading, read the published CHANGELOG.md for breaking changes.
  • Run your own integration tests against the sandbox after upgrades.
See also Production checklist.