Skip to main content

Overview

External Gateway mode is designed for teams who want UniBee to manage subscriptions, invoices, billing cycles and entitlements, while your own system or a third‑party gateway handles the actual payment and refunds. In this model:
  • UniBee handles:
    • Subscription lifecycle and billing cycles
    • Invoice generation and status
    • Entitlement logic (activation, renewal, cancellation)
    • Webhooks to your backend
  • Your system handles:
    • Creating payment orders
    • Showing a checkout page / cashier
    • Executing charge and refund on your own gateway
    • Calling UniBee External Gateway APIs to report results
Funds flow only between your customer and your payment system. UniBee does not charge cards directly; it updates invoice and subscription status based on the results you report.

Data Flow at a Glance

DirectionDescription
UniBee → Your SystemWhen UniBee creates/renews an invoice, it also creates a Payment and sends a payment.created webhook telling you “it’s time to try charging this invoice”. When the user clicks “Pay” on UniBee UI, UniBee opens an intermediate page and waits for your payment link.
Your System → UniBeeAfter your gateway finishes a payment or refund, your backend calls the External Gateway APIs (update_payment_link, mark_paid, mark_refunded) to update the invoice and subscription state in UniBee.
For high‑level product behavior from the invoice perspective, see also:
External Gateway Invoices.

1. Configuration and Security

1.1 Configure External Gateway in UniBee

Before integration, you need to configure one or more External Gateways in UniBee:
  1. Log in as a merchant → Configuration → Payment Gateways.
  2. Add and configure an External Gateway (similar to other gateways).
  3. For each External Gateway, UniBee provides:
    • A unique gatewayId
    • An External Gateway API Key (also called GatewayKey) used only for HMAC signatures
Use gatewayId to distinguish multiple external channels (e.g. custom_gateway_A, custom_gateway_B), and keep the GatewayKey strictly confidential.

1.2 Dual Authentication & Signature Rule

Every External Gateway API call requires two layers of authentication:
  1. Merchant OpenAPI auth
    • HTTP header Authorization: Bearer <UNIBEE_API_KEY>
  2. Request body signature using the GatewayKey:
    • Signature string (concatenate with | in this exact order):
      invoiceId|externalTransactionId|timestamp
    • Algorithm: HMAC-SHA256(GatewayKey, signatureString)
    • Encoding: hex string used as signature
    • Anti‑replay: timestamp must be within UniBee’s accepted time window (for example, ±5 minutes). Use current Unix timestamp in seconds.
All three External Gateway endpoints share the same rule:
  • POST /merchant/invoice/external_gateway_invoice/update_payment_link
  • POST /merchant/invoice/external_gateway_invoice/mark_paid
  • POST /merchant/invoice/external_gateway_invoice/mark_refunded
signatureString = invoiceId + "|" + externalTransactionId + "|" + timestamp
signature       = hex( HMAC_SHA256(GatewayKey, signatureString) )

2. Core APIs

Use this when you want UniBee’s UI (Checkout / invoice link / subscription detail) to redirect the user to your own checkout URL. Typical fields:
  • invoiceId — UniBee invoice ID
  • externalTransactionId — your order / payment ID
  • paymentLink — your fully qualified checkout URL
  • sendInvoice — optional, whether UniBee should send an invoice email
  • timestamp, signature — signed as described above
You can safely call this endpoint multiple times. UniBee always uses the latest paymentLink for the intermediate page and invoice link.

2.2 Mark Invoice as Paid

After your gateway confirms a successful charge, call this API so UniBee can:
  • Set the invoice status to Paid
  • Trigger subscription activation or renewal
  • Emit standard webhooks (e.g. invoice.paid, subscription.update.success)
  • API: Mark External Gateway Invoice As Paid
  • Path: POST /merchant/invoice/external_gateway_invoice/mark_paid
Key fields:
  • invoiceId — UniBee invoice ID
  • externalTransactionId — your payment order ID (also used for idempotency)
  • paidTime — optional Unix timestamp when payment succeeded
  • metadata — optional JSON with extra info
  • timestamp, signature — signed as above
The amount is always taken from the UniBee invoice. You do not need to send the amount in this call.

2.3 Mark Invoice as Refunded

When you complete a refund in your gateway (full or partial), call this API to sync the state in UniBee. Key fields mirror the paid API but use a refund ID for externalTransactionId. Use the same signing rule:
signatureString = invoiceId + "|" + refundId + "|" + timestamp

3. Webhook: payment.created

When UniBee decides it’s time to attempt payment for an External Gateway invoice (for example, before renewal, or when the user clicks “Pay”), it sends a payment.created webhook.

3.1 Identifying External Payments

In your webhook handler:
  • Check payment.gatewayId in the payload and compare it with your known External gatewayIds, or
  • Inspect the gateway object and check that:
    • gateway.gatewayType == 8 (External), or
    • gateway.gatewayName == "external" (depending on your configuration)
Once identified as External:
  1. Read invoiceId, paymentId, amount and currency from the event.
  2. Create/attach an order in your own system.
  3. Decide when/how to charge the user (immediately, or later).
  4. After charge succeeds, call mark_paid; on refund, call mark_refunded.

3.2 Typical Timing

  • Renewal invoices are usually generated a few days before the period end.
  • Around 2 hours before the billing period ends (configurable), UniBee:
    • Creates or reuses a Payment
    • Sends one payment.created event for External gateways
  • For subsequent automatic attempts, UniBee reuses the same Payment and does not send additional payment.created events.
You only need to react to the first payment.created per Payment.

4. Integration Patterns

  1. Your app calls UniBee to create a subscription / invoice with an External Gateway.
  2. UniBee returns an invoice link or Checkout link to show to the user.
  3. When the user clicks “Pay”, UniBee opens an External Gateway intermediate page:
    • The page polls the Payment / Invoice until a paymentLink is available.
  4. Your backend calls update_payment_link with your checkout URL.
  5. The intermediate page detects the paymentLink and redirects the user to your checkout.
  6. After successful payment, your backend calls mark_paid for the corresponding invoiceId and externalTransactionId.

Pattern B: Your Own Checkout Only (No UniBee UI)

  1. Your backend calls UniBee APIs to create subscriptions/invoices (with an External Gateway) and stores the invoiceId.
  2. You present your own checkout page; the user never sees UniBee’s checkout or intermediate pages.
  3. After the payment succeeds in your gateway, you call mark_paid.
  4. If a refund is processed later, you call mark_refunded.
In this pattern you do not need to call update_payment_link.

Pattern C: Invoice Email / Invoice Center

If you rely on UniBee’s invoice emails or invoice center:
  • Always integrate update_payment_link, so the invoice “Pay” button can redirect to your latest checkout URL.
  • When the order URL changes or expires, call update_payment_link again — UniBee will always use the newest value.

5. Best Practices

  • Use UniBee as the source of truth for invoices and subscriptions
    Even if your gateway handles the money, keep all invoices and subscription state in UniBee so reporting and entitlement logic stay consistent.
  • Drive state from your gateway events
    Only call mark_paid / mark_refunded after your own gateway definitively confirms the result (via its own webhook or API).
  • Keep payment links fresh
    If your checkout URLs can expire or change, always update them via update_payment_link before the user clicks “Pay”.
  • Subscribe to UniBee webhooks
    Use UniBee webhooks such as invoice.paid, invoice.refund.success, subscription.update.success to keep your internal systems and CRM/Billing dashboards in sync.
  • Leverage idempotency
    Use a stable externalTransactionId for each payment or refund. Calling mark_paid or mark_refunded multiple times with the same (invoiceId, externalTransactionId) is safe — UniBee treats it as idempotent and does not double‑charge or double‑refund.