Webhook updates

Realtime order updates for your backend

After an order is created, real-time updates about order state changes are sent to your configured webhook.

Webhook configuration

To configure your webhook:

  1. Head over to https://console.rye.com/account
  2. Enter a valid callback endpoint for your backend under the "Webhook section", and click save

That's it! On every order update, a webhook will be fired at your designated endpoint.

Webhook types

The webhook body is JSON formatted. If your project is Typescript based you can use these types.

export type Marketplace = AmazonMarketplace | ShopifyMarketplace;
export type AmazonMarketplace = 'amazon';
export type ShopifyMarketplace = 'shopify';

export type RyeWebhook =
  | PaymentSucceededWebhook
  | PaymentFailedWebhook
  | PaymentRefundedWebhook
  | OrderSubmissionStartedWebhook
  | OrderSubmissionSucceededWebhook
  | OrderPlacedWebhook
  | OrderFailedWebhook
  | TrackingObtainedWebhook;

type BaseWebhook = {
  // Unique identifier for the webhook
  id: string;
  // Unique ID of the checkout request
  requestId: string;
  // ID of developer who initiated the checkout request
  developerId: string;
  // Creation time of the webhook
  createdAt: string;
};

export enum WebhookType {
  PaymentSucceeded = 'PAYMENT_SUCCEEDED',
  PaymentFailed = 'PAYMENT_FAILED',
  PaymentRefunded = 'PAYMENT_REFUNDED',
  OrderSubmissionStarted = 'ORDER_SUBMISSION_STARTED',
  OrderSubmissionSucceeded = 'ORDER_SUBMISSION_SUCCEEDED',
  OrderPlaced = 'ORDER_PLACED',
  OrderFailed = 'ORDER_FAILED',
  TrackingObtained = 'TRACKING_OBTAINED',
}

export type PaymentSucceededWebhook = BaseWebhook & {
  type: WebhookType.PaymentSucceeded;
  data: { marketplace: Marketplace; amount: number };
};

export type PaymentFailedWebhook = BaseWebhook & {
  type: WebhookType.PaymentFailed;
  data: { marketplace: Marketplace };
};

export type PaymentRefundedWebhook = BaseWebhook & {
  type: WebhookType.PaymentRefunded;
  data: Record<string, never>;
};

export type OrderSubmissionStartedWebhook = BaseWebhook & {
  type: WebhookType.OrderSubmissionStarted;
  data: { marketplace: Marketplace };
};

export type OrderSubmissionSucceededWebhook = BaseWebhook & {
  type: WebhookType.OrderSubmissionSucceeded;
  data: { marketplace: Marketplace };
};

export type OrderPlacedWebhook = BaseWebhook & {
  type: WebhookType.OrderPlaced;
  data: AmazonOrderPlacedWebhook | ShopifyOrderPlacedData;
};
export type AmazonOrderPlacedWebhook = {
  marketplace: AmazonMarketplace;
  order: BasePlacedOrderDetails & {
    amazonOrders: BaseAmazonOrder[];
  };
};
export type BasePlacedOrderDetails = {
  currency: string;
  shippingCents: number;
  subtotalCents: number;
  taxCents: number;
  totalCents: number;
};
export type BaseAmazonOrder = {
  amazonOrderId: string;
  products: AmazonOrderRequestProduct[];
};

export type AmazonOrderRequestProduct = {
  quantity: number;
  productId: string;
};

export type ShopifyOrderPlacedData = {
  marketplace: ShopifyMarketplace;
  order: BasePlacedOrderDetails
  orderEmailOverride?: string;
};

export type OrderFailedWebhook = BaseWebhook & {
  type: WebhookType.OrderFailed;
  data: {
    marketplace: Marketplace;
    // Only for stripe
    refund?: StripeRefund;
    reasonCode?: OrderFailedReasonCode;
    reason?: string;
  };
};
export type OrderFailedReasonCode =
  | 'INTERNAL_ERROR'
  | 'OUT_OF_STOCK'
  | 'INVALID_REQUEST'
  | 'UNAUTHENTICATED'
  | 'PERMISSION_DENIED'
  | 'USER_REQUESTED';

export type TrackingObtainedWebhook = BaseWebhook & {
  type: WebhookType.TrackingObtained;
  data: AmazonTrackingObtainedData | ShopifyTrackingObtainedData;
};
export type AmazonTrackingObtainedData = {
  marketplace: AmazonMarketplace;
  order: {
    amazonOrders: (BaseAmazonOrder & AllOrNothing<TrackedOrderDetails>)[];
  };
};
export type TrackedOrderDetails = {
  trackingNumber: string;
  courierUrl: string;
  courierName: string;
};

export type AllOrNothing<T> = NeverFields<T> | T;
export type NeverFields<T> = {
  [K in keyof T]?: never;
};

export type ShopifyTrackingObtainedData = {
  marketplace: ShopifyMarketplace;
  order: {
    fulfillments: BaseShopifyOrderFulfillment[];
  };
};

export type BaseShopifyOrderFulfillment = {
  products: ShopifyOrderRequestProduct[];
  trackingDetails: TrackedOrderDetails[];
};
export type ShopifyOrderRequestProduct = {
  quantity: number;
  variantId: string;
};

export type StripeRefund = {
  /**
   * Amount, in %s.
   */
  amount: number;

  /**
   * Time at which the object was created. Measured in seconds since the Unix epoch.
   */
  created: number;

  /**
   * Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. Must be a [supported currency](https://stripe.com/docs/currencies).
   */
  currency: string;

  /**
   * An arbitrary string attached to the object. Often useful for displaying to users. (Available on non-card refunds only)
   */
  description?: string;

  /**
   * This is the transaction number that appears on email receipts sent for this refund.
   */
  receipt_number: string | null;

  /**
   * Status of the refund. For credit card refunds, this can be `pending`, `succeeded`, or `failed`. For other types of refunds, it can be `pending`, `requires_action`, `succeeded`, `failed`, or `canceled`. Refer to our [refunds](https://stripe.com/docs/refunds#failed-refunds) documentation for more details.
   */
  status: string | null;
};

Otherwise, you can generate types for your preferred language using the following JSON Schema: Click to download.