Blog

REST APIs for ERP, ecommerce, and payment gateway integrations

Updated: 13 min read
apirestintegrationserpwebhookslaravel

Connecting an ERP with ecommerce and a payment gateway takes more than “building an endpoint”. It requires clear contracts, robust authentication, predictable error handling, and idempotent webhooks. Without that, every new integration becomes technical debt.

This article describes REST API design for server-to-server integrations between ERPs, online stores, and gateways such as Yappy, BAC, or Paguelo Fácil.

Design principles

  • Explicit contracts: each endpoint documents request, response, and error codes.
  • Idempotency: retrying a POST does not duplicate orders or charges.
  • Versioning: breaking changes go to /v2/, not silent patches.
  • Minimal authentication: scopes per resource, never credentials in query strings.
  • Observability: correlation ID on every request to trace cross-system flows.

Resource structure

Recommended pattern for ecommerce + ERP:

ResourceMethodsPurpose
/v1/ordersPOST, GETCreate and query orders
/v1/orders/{id}/statusPATCHUpdate status (with validation)
/v1/products/syncPOSTSync catalog from ERP
/v1/webhooks/paymentPOSTReceive gateway confirmation
/v1/inventory/{sku}GETQuery real-time stock

Server-to-server authentication

  • API keys with minimal scopes (stock read-only, orders write-only).
  • HMAC on webhooks: the receiver validates the signature with a shared secret.
  • OAuth2 client credentials when the provider requires it (SAP, some cloud ERPs).
  • Documented key rotation; never in repos or Docker images.

Webhooks vs polling

Webhooks for business events: payment confirmed, stock updated, shipment dispatched. The sender notifies; the receiver validates the signature, persists, and responds 200.

Polling only as a fallback or when the external system does not support callbacks. Always with exponential backoff and a retry limit.

Error handling

Consistent responses make integration easier:


            {
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "Order 12345 does not exist",
    "correlation_id": "abc-123"
  }
}
          
  • Semantic HTTP codes: 400 (invalid input), 401 (auth), 404 (not found), 409 (conflict/idempotency), 429 (rate limit), 500 (internal error).
  • Never expose stack traces or SQL queries in production.
  • correlation_id in header and body for cross-system support.

Resilience when the ERP is down

  1. Ecommerce creates the order locally with pending_sync status.
  2. A queued job tries to sync with the ERP with retries and backoff.
  3. If it fails after N attempts, it goes to a dead-letter queue and alerts the team.
  4. The customer sees order confirmation; synchronization is reconciled later.

Versioning without breaking clients

  • /v1/ in URL or Accept-Version: 1 header.
  • Published and updated OpenAPI/Swagger with each release.
  • Deprecation policy: 90-day notice before removing an endpoint.
  • Contract tests (Pact or similar) between consumer and provider.

Integration checklist

  1. Documented contract (OpenAPI) with request/response examples.
  2. Authentication with minimal scopes and key rotation.
  3. Idempotency on creation POST (header Idempotency-Key).
  4. Webhooks with HMAC validation and sender retries.
  5. Queues for async sync with dead-letter.
  6. Logs with correlation ID, no PII or secrets.
  7. Rate limiting on public endpoints.
  8. Separate environments (sandbox/prod) with distinct credentials.

Connect with integrations, payments in Panama, and API protection .

Frequently asked questions

REST or GraphQL for ERP integrations?

REST remains the most predictable option for B2B integrations and payment gateways. GraphQL makes sense when the consumer is your own frontend with flexible query needs.

How do you version without breaking clients?

Versioning in URL or header (`/v1/`), documented contracts (OpenAPI), and a deprecation policy with dates. Breaking changes go to `/v2/`, not silent patches.

Webhooks or polling?

Webhooks for business events (payment confirmed, stock updated). Polling only as a fallback or when the external system does not support callbacks. Always with retries and idempotency.

How do you authenticate server-to-server integrations?

API keys with minimal scopes, HMAC on webhooks, OAuth2 client credentials when the provider requires it. Never credentials in query strings or repos.

What happens if the ERP is down?

Queues with retries, dead-letter queue, and visible intermediate states. Ecommerce should not block on an ERP timeout; enqueue and reconcile.