/** * Typed shapes for the PayMe API surface used by partners and direct sellers. * * Field names are PayMe's, verbatim and in snake_case, on purpose: they line up * one-for-one with the docs at https://docs.payme.io. Renaming them to camelCase * inside the transport layer is how typos like `sellerPaymeId` silently become an * omitted required field. The mapping to friendlier names happens in your service * layer, not here. * * A partner authenticates with its partner key plus the seller's MPL. A direct * seller authenticates with its MPL alone (`seller_payme_id`, or the * `PayMe-Merchant-Key` header on REST-shaped endpoints) and has no partner key. */ /** Every PayMe response carries this envelope. `status_code: 0` means success. */ export interface PayMeEnvelope { status_code: number; status_error_code?: number; status_error_details?: string; status_additional_info?: unknown; /** Request id. Log it with every error and quote it to PayMe support. */ session?: string; payme_status?: string; } // --------------------------------------------------------------------------- // Sellers (partners only) // --------------------------------------------------------------------------- /** POST /create-seller — https://docs.payme.io/payments/merchants-management/post-create-seller */ export interface CreateSellerRequest { payme_client_key: string; seller_first_name: string; seller_last_name: string; seller_social_id: string; /** dd/mm/yyyy with leading zeros — NOT ISO. */ seller_birthdate: string; /** dd/mm/yyyy with leading zeros — issuing date of the social ID document. */ seller_social_id_issued: string; /** 0 = male, 1 = female. */ seller_gender: number; seller_email: string; seller_phone: string; seller_contact_email?: string; seller_contact_phone?: string; /** Israeli bank code: https://docs.payme.io/payments/codes-statuses/banks-in-israel. 54 works in sandbox. */ seller_bank_code: number; seller_bank_branch: number; seller_bank_account_number: string; /** Max 255 chars. */ seller_description: string; seller_site_url: string; /** PayMe MCC: https://docs.payme.io/marketplaces-and-platforms/seller-reference/mcc-list. */ seller_person_business_type: number; /** Incorporation type: https://docs.payme.io/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il. */ seller_inc: number; /** Business ID (ח.פ / ע.מ). May be required for your account. */ seller_inc_code?: string; /** 1 = card-not-present (online), 2 = card-present. */ seller_retail_type?: number; /** Required when seller_inc !== 1. */ seller_merchant_name?: string; seller_merchant_name_en?: string; seller_address_city: string; seller_address_street: string; seller_address_street_number: string; /** ISO 3166 alpha-2, e.g. "IL". */ seller_address_country: string; /** 0.00–60.00 — the marketplace's cut, in percent, VAT included. */ market_fee?: number; /** "en" or "he". Controls the language of PayMe's error messages. */ language?: string; /** A named settings preset. The valid values are issued by your PayMe account manager. */ seller_plan?: string; /** Your own id for this seller. A plan can refuse a field it fixes, with error 790 naming the field. */ seller_id?: string; } export interface CreateSellerResponse extends PayMeEnvelope { /** The seller's MPL. This is the id you store and send on every later call. */ seller_payme_id: string; /** Ignore this field and do not store it: it is a random value nothing checks. */ seller_payme_secret: string; seller_public_key?: { /** The public key the browser needs for Hosted Fields / JSAPI tokenization. */ uuid: string; description: string; is_active: boolean; }; seller_id: string | null; /** Link that walks the seller through completing their onboarding details. */ seller_dashboard_signup_link?: string; } /** GET /sellers/{seller_payme_id}/public-keys — partner-only, auth via the `PayMe-Partner-Key` header. */ export interface SellerPublicKeysResponse extends PayMeEnvelope { seller_payme_id: string; items_total: number; items: Array<{ uuid: string; description: string }>; } /** One seller as returned by POST /get-sellers. Trimmed to the fields a partner integration usually reads. */ export interface PayMeSellerSummary { seller_payme_id: string; seller_id: string | null; seller_created: string; seller_active: boolean; seller_approved: boolean; seller_approved_date: string | null; seller_personal_details?: Record; seller_business_details?: Record; seller_address?: Record; seller_fees?: Record; seller_currencies?: string[]; /** * The seller's balance, keyed by currency. `wallet_total` is everything held; * `wallet_releasable` is the part already past its release date and therefore * withdrawable. Both are in minor units. */ seller_wallets?: Record< string, { wallet_currency: string; wallet_total: number; wallet_releasable: number } >; } export interface GetSellersResponse extends PayMeEnvelope { items_count: number; items: PayMeSellerSummary[]; } // --------------------------------------------------------------------------- // Sales // --------------------------------------------------------------------------- /** POST /generate-sale — https://docs.payme.io/payments/hosted-payment-page/post-generate-sale */ export interface GenerateSaleRequest { /** The MPL of the seller the money goes to. Server-side only: PayMe calls it "your private key in PayMe system". */ seller_payme_id: string; /** Minor units (agorot/cents). Default minimum 500. */ sale_price: number; currency: string; /** Shown to the buyer and on the invoice. Max 500 chars. */ product_name: string; /** Your own order id. Comes back on the callback so you can correlate. */ transaction_id?: string; /** * "1".."12" fixes the count; "103"/"106"/"109"/"112" lets the buyer pick up * to 3/6/9/12. Note it is a STRING. */ installments?: string; /** Partners: override the seller's default marketplace cut for this one sale. */ market_fee?: number; /** "sale" (J4, default) | "authorize" (J5 — reserve now, capture later) | "template" | "token" | "seller-token" | "credit". */ sale_type?: string; /** "credit-card" (default), "bit", "paypal", "google-pay", "apple-pay", "multi", ... */ sale_payment_method?: string; /** "1" also captures a reusable buyer token on this payment. Mutually exclusive with buyer_key. */ capture_buyer?: string; /** Charge a previously captured token. Mutually exclusive with capture_buyer. */ buyer_key?: string; /** Charge a partner token: the `uuid` from POST /sellers/{mpl}/tokens. */ token?: string; /** Where PayMe POSTs the server-to-server notification. */ sale_callback_url?: string; /** Where the buyer's browser is redirected after paying. */ sale_return_url?: string; sale_send_notification?: boolean; sale_email?: string; sale_mobile?: string; sale_name?: string; buyer_name?: string; buyer_email?: string; buyer_phone?: string; /** "he" (default) or "en" — sets the language of the payment page itself. */ language?: string; /** Layout for the bit payment method: "dynamic" | "qr-sms" | "dynamic-loose". */ layout?: string; } export interface GenerateSaleResponse extends PayMeEnvelope { /** The hosted payment page. Put it in an iframe, or redirect the buyer to it. */ sale_url: string; /** PayMe's sale id (SALE...-...-...-...). Store it; every later action needs it. */ payme_sale_id: string; /** Short numeric code, for display and support only. */ payme_sale_code: number; price: number; transaction_id: string | null; currency: string; sale_payment_method?: string; } /** * POST /pay-sale — charges a sale created by generate-sale. * * Two very different callers use this endpoint: * - PCI-compliant merchants sending raw PAN (credit_card_number/exp/cvv). * - Everyone else sending `buyer_key`: a token from Hosted Fields or from an * earlier capture_buyer sale. No card data touches your server. * Never send raw card data unless you are PCI DSS certified. */ export interface PaySaleRequest { seller_payme_id: string; payme_sale_id: string; sale_price: string; currency: string; installments: string; buyer_key?: string; credit_card_number?: string; credit_card_exp?: string; credit_card_cvv?: string; buyer_name?: string; buyer_email?: string; buyer_phone?: string; sale_return_url?: string; sale_callback_url?: string; /** "1" to tokenize — only with raw card fields (PCI). Never together with buyer_key. */ capture_buyer?: string; /** * 3-D Secure with Hosted Fields: the hash from `PayMe.clientData()` in the * buyer's browser. The answer may then be a PaySaleChallenge. * https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide */ meta_data_jwt?: string; language?: string; } /** * pay-sale's answer when 3-D Secure needs a buyer challenge: send the buyer's * browser to `redirect_url`. The final result arrives by callback. */ export interface PaySaleChallenge { status_code: 5; status_message?: string; redirect_url: string; } /** The "sale details" payload — returned by pay-sale/capture-sale and POSTed as a callback. */ export interface PayMeSaleDetails extends PayMeEnvelope { payme_sale_id: string; payme_sale_code: number; sale_created: string; sale_status: string; payme_sale_status?: string; currency: string; /** YOUR order id, echoed back. */ transaction_id: string | null; is_token_sale: boolean; price: number; /** * md5 over PARTNER credentials and two ids. Never proof of payment. A partner * checks it (partner-signature.ts), a direct seller cannot, and both confirm * the sale with get-transactions (sale-query-verification.ts). */ payme_signature: string | null; sale_description?: string; sale_type?: string; /** PayMe's transaction id. Half of the signature input. */ payme_transaction_id?: string; payme_transaction_total?: string; payme_transaction_card_brand?: string; payme_transaction_auth_number?: string; buyer_name?: string; buyer_email?: string; buyer_phone?: string; buyer_card_mask?: string; buyer_card_exp?: string; buyer_social_id?: string; /** Reusable token — present only when capture_buyer was requested. */ buyer_key?: string; installments?: number; sale_paid_date?: string; sale_release_date?: string | null; sale_invoice_url?: string; /** The callback's event type: sale-complete, sale-authorized, refund, ... */ notify_type?: string; } /** POST /capture-sale — settle an authorization (J5). */ export interface CaptureSaleRequest { /** Partners send their partner key. A direct seller has none. */ payme_client_key?: string; seller_payme_id: string; payme_sale_id: string; /** * Partial capture: the amount to settle, minor units, within your account's * capture limit. Omit for a full capture. What happens to the rest of the * authorized amount is not confirmed here; ask PayMe before relying on it. */ sale_price?: number; /** Without it PayMe returns `status_error_details` in Hebrew. */ language?: string; } /** POST /refund-sale — full refund, or partial when sale_refund_amount is set. */ export interface RefundSaleRequest { /** Partners send their partner key. A direct seller has none. */ payme_client_key?: string; seller_payme_id: string; payme_sale_id: string; /** Partial refunds only: minor units, minimum 500. Omit for a full refund or a void. */ sale_refund_amount?: number; language?: string; } export interface RefundSaleResponse extends PayMeEnvelope { /** * "refunded" needs one refund for the full amount from a status other than * "partial-refund". A sale refunded in full through several partial refunds * stays "partial-refund": track the refunded total yourself. */ sale_status: string; payme_transaction_id?: string; payme_transaction_total?: number; sale_invoice_url?: string | null; refunded_from_creditcard?: boolean; } // --------------------------------------------------------------------------- // Query APIs // --------------------------------------------------------------------------- /** * POST /get-transactions — a direct seller authenticates with its MPL alone. * https://docs.payme.io/payments/query-apis/post-get-transactions */ export interface GetTransactionsRequest { seller_payme_id: string; /** Required only when a partner queries several sellers at once. */ payme_client_key?: string; /** PayMe's sale id. */ sale_payme_id?: string; /** YOUR order id, as sent on generate-sale. */ transaction_id?: string; /** PayMe's transaction guid. */ payme_transaction_id?: string; /** Defaults to 1 (sale). An uncaptured authorization is 40. */ transaction_type?: number; page?: number; /** Max 500. */ page_size?: number; } /** * One row per transaction on a sale. * Enum-like fields arrive as strings ("completed", "ILS", "credit-card"). * Only the fields verification and common reads rely on are typed; rows carry many more. */ export interface PayMeTransactionRow { seller_payme_id?: string; sale_payme_id?: string; /** YOUR order id, echoed back. */ transaction_id?: string; payme_transaction_id?: string; /** "Y-m-d H:i:s", e.g. "2026-10-12 14:33:07" — a space, not "T". */ transaction_created_at?: string; sale_status?: string; transaction_status?: string; sale_type?: number; /** Authorize, Debit, Capture, Refund, Partial Refund, Void, ... */ transaction_action?: string; sale_currency?: string; /** Minor units. */ transaction_price?: number; /** The gateway's code. 20000 means permitted. */ transaction_error_code?: number | null; [key: string]: unknown; } /** { status_code, session, items_count, items }. Row timestamps are "Y-m-d H:i:s". */ export interface GetTransactionsResponse extends PayMeEnvelope { items_count?: number; items?: PayMeTransactionRow[]; } /** * POST /get-subscriptions — a direct seller authenticates with its MPL alone. * Send `seller_payme_id` in the JSON body as a single value on every query: only * the body value filters the rows, so a key sent only in a header can return * other sellers' subscriptions. * https://docs.payme.io/payments/query-apis/post-get-subscriptions */ export interface GetSubscriptionsRequest { seller_payme_id: string; /** Partners may also send their partner key. */ payme_client_key?: string; sub_payme_id?: string; page?: number; page_size?: number; } /** One subscription as get-subscriptions returns it. */ export interface PayMeSubscriptionRow { seller_payme_id?: string; sub_payme_id?: string; /** A status code — normalise before use (normaliseSubscriptionStatus). */ sub_status?: string | number; sub_price?: number; sub_currency?: string; sub_iterations_completed?: string | number; sub_paid?: boolean; sub_payment_date?: string; [key: string]: unknown; } export interface GetSubscriptionsResponse extends PayMeEnvelope { items_count?: number; items?: PayMeSubscriptionRow[]; } // --------------------------------------------------------------------------- // Tokenization // --------------------------------------------------------------------------- /** * POST /sellers/{mpl}/tokens — partner tokenization. * * Takes the payment instrument for a given payment method and returns a buyer * token with partner-level privacy, stored under the MPL in the path, so it can * be charged later on behalf of your sellers. Charge it by sending the * response's `uuid` as `token` on POST /generate-sale. */ export interface SellerTokenRequest { payment: { /** "credit-card", "bit", "il-direct-debit", ... */ method: string; [key: string]: unknown; }; /** Required: `customer.email`. */ customer: { email: string; [key: string]: unknown; }; [key: string]: unknown; } export interface SellerTokenResponse { /** The buyer token. Send it as `token` on POST /generate-sale, not as `buyer_key`. */ uuid?: string; redirect_url?: string; [key: string]: unknown; } /** * POST /get-buyer-key — recover the token captured during a paid sale or * subscription. Send exactly one of payme_sale_id and sub_payme_id, plus * seller_payme_id or payme_client_key. A partner-privacy token is refused when * seller_payme_id is sent. */ export interface GetBuyerKeyRequest { payme_sale_id?: string; sub_payme_id?: string; seller_payme_id?: string; payme_client_key?: string; } export interface GetBuyerKeyResponse extends PayMeEnvelope { payme_sale_id?: string; sub_payme_id?: string; buyer_key: string; buyer_card_mask: string; buyer_card_expiry: string; buyer_card_brand: string; } // --------------------------------------------------------------------------- // Subscriptions // --------------------------------------------------------------------------- /** POST /generate-subscription */ export interface GenerateSubscriptionRequest { seller_payme_id: string; /** Price of ONE iteration, in minor units. Default minimum 500. A number or a digit string. */ sub_price: number | string; sub_currency: string; sub_description: string; /** "1" daily | "2" weekly | "3" monthly | "4" annually. */ sub_iteration_type: string; /** How many iterations to run. -1 means "until cancelled". */ sub_iterations: number; /** dd/mm/yyyy. */ sub_start_date?: string; sub_callback_url?: string; sub_return_url?: string; /** Activate immediately against an existing token instead of showing a page. */ buyer_key?: string; language?: string; } export interface GenerateSubscriptionResponse extends PayMeEnvelope { /** Hosted page where the buyer enters payment details to activate the subscription. */ sub_url?: string; seller_payme_id: string; /** PayMe's subscription id (SUB...). Store it; every later action needs it. */ sub_payme_id: string; sub_payme_code: string | number; sub_created: string; sub_start_date: string | null; sub_next_date: string | null; /** 1 initial | 2 active | 3 paused | 4 failed | 5 cancelled | 6 completed | 7 failed, will retry. */ sub_status: number | string; sub_iteration_type: number | string; sub_currency: string; sub_price: number | string; sub_description: string; sub_iterations: number | string; sub_iterations_completed?: number; sub_iterations_left?: number | string; sub_paid?: boolean; sub_error_text?: string | null; } /** * The subscription payload as POSTed to your callback URL. It carries NO * payme_signature and NO transaction_id: re-read with get-subscriptions. */ export interface PayMeSubscriptionDetails extends PayMeEnvelope { seller_payme_id: string; sub_payme_id: string; sub_payme_code: number; sub_created: string; sub_start_date: string | null; sub_prev_date: string | null; sub_next_date: string | null; sub_status: number; sub_iteration_type: number; sub_currency: string; sub_price: number; sub_description: string; sub_iterations: number; sub_iterations_completed: number; sub_iterations_skipped?: number; sub_iterations_left: number; sub_paid: boolean; sub_error_text?: string | null; buyer_card_mask?: string; buyer_card_exp?: string; buyer_name?: string; buyer_email?: string; /** On sub-iteration-success: the sale created for this iteration. */ payme_sale_id?: string; payme_sale_code?: number; /** sub-create | sub-active | sub-iteration-success | sub-failure | ... */ notify_type?: string; } /** POST /cancel-subscription — terminal. POST /pause-subscription — reversible. */ export interface SubscriptionActionRequest { seller_payme_id: string; sub_payme_id: string; language?: string; } /** * PATCH /subscriptions/{sub_payme_id}/set-price — applies from the next * iteration. (Resume is PATCH /subscriptions/{sub_payme_id}/resume with the MPL * in the `PayMe-Merchant-Key` header and no body.) */ export interface SetSubscriptionPriceRequest { seller_payme_id: string; /** A STRING here, a number on generate-subscription. Minor units. */ sub_price: string; language?: string; } // --------------------------------------------------------------------------- // Partner callbacks // --------------------------------------------------------------------------- /** * The seller payload as POSTed to a partner's callback URL. It carries NO * payme_signature: ignore the body and re-read with get-sellers. */ export interface PayMeSellerCallback extends PayMeEnvelope { seller_payme_id: string; seller_id: string | null; seller_created: string; seller_active: boolean; seller_approved: boolean; seller_email?: string; seller_merchant_name?: string; seller_market_fee?: string | number; /** seller-create | seller-update | seller-approve. */ notify_type?: string; [key: string]: unknown; }