{"openapi":"3.0.0","paths":{"/applications":{"post":{"description":"Creates an application and returns its generated API key.","operationId":"ApplicationsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApplicationDto"}}}},"responses":{"201":{"description":"Application created."}},"security":[{"bearer":[]}],"summary":"Register a new application","tags":["Applications"]},"get":{"operationId":"ApplicationsController_findAll","parameters":[],"responses":{"200":{"description":"List of applications.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"List all applications","tags":["Applications"]}},"/applications/{id}":{"get":{"operationId":"ApplicationsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get an application by id","tags":["Applications"]},"post":{"operationId":"ApplicationsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApplicationDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Update an application","tags":["Applications"]},"delete":{"operationId":"ApplicationsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete an application","tags":["Applications"]}},"/payments":{"post":{"description":"Creates a payment through the selected provider and returns the stored payment plus an optional `checkoutUrl`.","operationId":"PaymentsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentDto"}}}},"responses":{"201":{"description":"Payment created.","content":{"application/json":{"schema":{"example":{"data":{"id":"uuid","applicationId":"application-uuid","applicationOrderId":"ORDER-12345","externalId":"payment-ext-12345","amount":50000,"currency":"IDR","status":"PENDING","provider":"XENDIT","paymentMethod":"BCA","checkoutUrl":"https://checkout.example.com/invoices/abc","createdAt":"2026-03-05T12:00:00.000Z"},"checkoutUrl":"https://checkout.example.com/invoices/abc"}}}}},"400":{"description":"Invalid request or unsupported provider."},"401":{"description":"Missing or invalid API key."}},"security":[{"X-API-Key":[]}],"summary":"Create a payment request","tags":["Payments"]},"get":{"description":"Returns a paginated list of payments belonging to the authenticated application.","operationId":"PaymentsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (1-based).","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page.","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}}],"responses":{"200":{"description":"Paginated list of payments.","content":{"application/json":{"schema":{"example":{"data":[{"id":"665f1c2a9b1e4a0012ab34cd","applicationId":"665f1c2a9b1e4a0012ab0000","applicationOrderId":"ORDER-12345","externalId":"payment-ext-12345","amount":50000,"currency":"IDR","status":"PENDING","provider":"MAYAR","paymentMethod":"QRIS","createdAt":"2026-03-05T12:00:00.000Z"}],"meta":{"page":1,"limit":10,"total":1,"totalPages":1}}}}}}},"security":[{"X-API-Key":[]}],"summary":"List payments","tags":["Payments"]}},"/payments/payment-link":{"post":{"description":"Creates a hosted checkout link (Xendit invoice, Midtrans Snap, or Mayar invoice).","operationId":"PaymentsController_createPaymentLink","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentLinkDto"}}}},"responses":{"201":{"description":"Payment link created."},"400":{"description":"Invalid request or unsupported provider."}},"security":[{"X-API-Key":[]}],"summary":"Create a payment link","tags":["Payments"]}},"/payments/save-payment-method":{"post":{"description":"Tokenizes/stores a payment method. Supported by Xendit and Midtrans only; Mayar returns 400.","operationId":"PaymentsController_savePaymentMethod","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavePaymentMethodDto"}}}},"responses":{"201":{"description":"Payment method saved."},"400":{"description":"Unsupported provider or missing card details."}},"security":[{"X-API-Key":[]}],"summary":"Save a payment method","tags":["Payments"]}},"/payments/xendit-callback":{"post":{"description":"Called by Xendit when a payment status changes.","operationId":"PaymentsController_handleXenditCallback","parameters":[{"name":"x-callback-token","required":true,"in":"header","description":"Must match `XENDIT_WEBHOOK_TOKEN`.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentCallbackDto"}}}},"responses":{"200":{"description":"Callback processed."},"401":{"description":"Invalid callback token."}},"security":[{"X-API-Key":[]}],"summary":"Xendit callback","tags":["Webhooks"]}},"/payments/midtrans-callback":{"post":{"description":"Called by Midtrans when a payment status changes.","operationId":"PaymentsController_handleMidtransCallback","parameters":[{"name":"x-midtrans-token","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentCallbackDto"}}}},"responses":{"200":{"description":"Callback processed."}},"security":[{"X-API-Key":[]}],"summary":"Midtrans callback","tags":["Webhooks"]}},"/payments/mayar-callback":{"post":{"description":"Called by Mayar when an invoice status changes (e.g. `payment.received`).","operationId":"PaymentsController_handleMayarCallback","parameters":[{"name":"token","required":false,"in":"query","description":"Shared secret, required when `MAYAR_WEBHOOK_TOKEN` is configured.","schema":{}},{"name":"x-mayar-token","in":"header","description":"Optional. Required only when `MAYAR_WEBHOOK_TOKEN` is configured. Mayar sends no custom header, so the token is normally passed as the `token` query parameter of the registered webhook URL.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentCallbackDto"}}}},"responses":{"200":{"description":"Callback processed."}},"security":[{"X-API-Key":[]}],"summary":"Mayar.id callback","tags":["Webhooks"]}},"/subscriptions":{"post":{"operationId":"SubscriptionsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionDto"}}}},"responses":{"201":{"description":"Subscription created."}},"security":[{"X-API-Key":[]}],"summary":"Create a subscription","tags":["Subscriptions"]},"get":{"operationId":"SubscriptionsController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (1-based).","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page.","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}}],"responses":{"200":{"description":"Paginated list of subscriptions.","content":{"application/json":{"schema":{"example":{"data":[],"meta":{"page":1,"limit":10,"total":0,"totalPages":0}}}}}}},"security":[{"X-API-Key":[]}],"summary":"List subscriptions for the application","tags":["Subscriptions"]}},"/subscriptions/{id}":{"get":{"operationId":"SubscriptionsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Get a subscription by id","tags":["Subscriptions"]},"put":{"operationId":"SubscriptionsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubscriptionDto"}}}},"responses":{"200":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Update a subscription","tags":["Subscriptions"]},"delete":{"operationId":"SubscriptionsController_cancel","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Cancel a subscription","tags":["Subscriptions"]}},"/subscriptions/{id}/pause":{"post":{"operationId":"SubscriptionsController_pause","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Pause a subscription","tags":["Subscriptions"]}},"/subscriptions/{id}/resume":{"post":{"operationId":"SubscriptionsController_resume","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Resume a subscription","tags":["Subscriptions"]}},"/subscriptions/xendit-callback":{"post":{"description":"Called by Xendit for recurring plan events.","operationId":"SubscriptionsController_handleXenditCallback","parameters":[{"name":"x-callback-token","required":true,"in":"header","description":"Must match `XENDIT_WEBHOOK_TOKEN`.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCallbackDto"}}}},"responses":{"201":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Xendit subscription callback","tags":["Webhooks"]}},"/subscriptions/midtrans-callback":{"post":{"description":"Called by Midtrans for subscription status changes.","operationId":"SubscriptionsController_handleMidtransCallback","parameters":[{"name":"x-midtrans-token","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCallbackDto"}}}},"responses":{"201":{"description":""}},"security":[{"X-API-Key":[]}],"summary":"Midtrans subscription callback","tags":["Webhooks"]}},"/login":{"post":{"description":"Exchanges admin credentials for a short-lived JWT.","operationId":"AdminController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLoginDto"}}}},"responses":{"200":{"description":"Login successful.","content":{"application/json":{"schema":{"example":{"token":"jwt-token"}}}}},"400":{"description":"Missing username or password."},"401":{"description":"Invalid credentials."}},"summary":"Admin login","tags":["Admin"]}},"/admin/dashboard":{"get":{"description":"Aggregated application, payment and subscription statistics, a 30-day volume trend and the most recent activity.","operationId":"AdminController_getDashboard","parameters":[],"responses":{"200":{"description":"Dashboard summary."}},"security":[{"bearer":[]}],"summary":"Dashboard summary","tags":["Admin"]}},"/admin/applications":{"get":{"description":"Returns every registered application, including its API key.","operationId":"AdminController_getApplications","parameters":[],"responses":{"200":{"description":"List of applications.","content":{"application/json":{"schema":{"example":{"data":[{"id":"uuid","name":"My Store"}]}}}}}},"security":[{"bearer":[]}],"summary":"List applications","tags":["Admin"]},"post":{"description":"Creates an application and returns its generated API key. Use the returned key as the `X-API-Key` header.","operationId":"AdminController_createApplication","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApplicationDto"}}}},"responses":{"201":{"description":"Application created.","content":{"application/json":{"schema":{"example":{"data":{"id":"uuid","apiKey":"generated-api-key"}}}}}},"400":{"description":"Invalid request body."}},"security":[{"bearer":[]}],"summary":"Register an application","tags":["Admin"]}},"/admin/applications/{id}":{"get":{"description":"Returns a single application wrapped in a `data` envelope.","operationId":"AdminController_getApplicationById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Application details.","content":{"application/json":{"schema":{"example":{"data":{"id":"uuid","name":"My Store"}}}}}},"404":{"description":"Application not found."}},"security":[{"bearer":[]}],"summary":"Get an application by id","tags":["Admin"]},"post":{"description":"Updates the name, webhook URLs or active flag of an application. Omitted fields are left untouched; an empty webhook URL clears it.","operationId":"AdminController_updateApplication","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApplicationDto"}}}},"responses":{"200":{"description":"Application updated.","content":{"application/json":{"schema":{"example":{"data":{"id":"uuid","name":"My Store"}}}}}},"400":{"description":"Invalid request body."},"404":{"description":"Application not found."}},"security":[{"bearer":[]}],"summary":"Update an application","tags":["Admin"]},"delete":{"description":"Permanently removes an application. Its API key stops working immediately.","operationId":"AdminController_deleteApplication","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Application deleted.","content":{"application/json":{"schema":{"example":{"data":{"id":"uuid","deleted":true}}}}}},"404":{"description":"Application not found."}},"security":[{"bearer":[]}],"summary":"Delete an application","tags":["Admin"]}},"/admin/payments":{"get":{"description":"Paginated payments across every application.","operationId":"AdminController_getPayments","parameters":[{"name":"endDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"enum":["PENDING","SUCCESS","FAILED","EXPIRED"],"type":"string"}},{"name":"applicationId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Paginated list of payments."}},"security":[{"bearer":[]}],"summary":"List payments","tags":["Admin"]}},"/admin/subscriptions":{"get":{"description":"Paginated subscriptions across every application.","operationId":"AdminController_getSubscriptions","parameters":[{"name":"endDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"enum":["ACTIVE","PAUSED","CANCELLED","EXPIRED","FAILED"],"type":"string"}},{"name":"applicationId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Paginated list of subscriptions."}},"security":[{"bearer":[]}],"summary":"List subscriptions","tags":["Admin"]}},"/admin/providers":{"get":{"description":"Returns configured payment providers (required credentials present) with their enable state, capability set and usage counts. Pass `includeUnconfigured=true` to include providers missing required credentials.","operationId":"AdminController_getProviders","parameters":[{"name":"includeUnconfigured","required":false,"in":"query","description":"Include providers whose required credentials are not configured.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"List of payment providers."}},"security":[{"bearer":[]}],"summary":"List payment providers","tags":["Admin"]}},"/admin/providers/{id}":{"put":{"description":"Toggles a provider. Disabled providers reject new payments and subscriptions (callbacks still reconcile).","operationId":"AdminController_updateProvider","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderDto"}}}},"responses":{"200":{"description":"Updated provider."},"400":{"description":"Unknown provider."}},"security":[{"bearer":[]}],"summary":"Enable or disable a payment provider","tags":["Admin"]}}},"info":{"title":"PGLink Payment Aggregator API","description":"Unified payment aggregator API for Indonesia.\n\nSupports **Xendit**, **Midtrans** and **Mayar.id** behind a single, \nconsistent interface with payment requests, payment links, \nsubscriptions and webhook forwarding.\n\n## Authentication\n- **Applications API** uses a JWT bearer token.\n- **Payments & Subscriptions API** uses the `X-API-Key` header \n(the key returned when an application is registered).","version":"1.0","contact":{}},"tags":[{"name":"Applications","description":"Manage applications and API keys (JWT)."},{"name":"Payments","description":"Create and list payments (API key)."},{"name":"Subscriptions","description":"Manage recurring subscriptions (API key)."},{"name":"Webhooks","description":"Provider callback endpoints (called by providers)."},{"name":"Admin","description":"Admin dashboard and provider management (JWT)."}],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"JWT issued for the Applications API."},"X-API-Key":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Application API key for payment endpoints."}},"schemas":{"CreateApplicationDto":{"type":"object","properties":{"name":{"type":"string","description":"Application name.","example":"My E-commerce Store"},"webhookUrl":{"type":"string","description":"URL that receives payment status webhooks.","example":"https://my-store.com/webhook/payment"},"subscriptionWebhookUrl":{"type":"string","description":"URL that receives subscription status webhooks.","example":"https://my-store.com/webhook/subscription"}},"required":["name"]},"UpdateApplicationDto":{"type":"object","properties":{"name":{"type":"string","description":"Application name."},"webhookUrl":{"type":"string","description":"Payment webhook URL."},"subscriptionWebhookUrl":{"type":"string","description":"Subscription webhook URL."},"isActive":{"type":"boolean","description":"Whether the application (and its API key) is active."}}},"CreatePaymentDto":{"type":"object","properties":{"applicationOrderId":{"type":"string","description":"Your internal order identifier.","example":"ORDER-12345"},"amount":{"type":"number","description":"Payment amount in the smallest currency unit (e.g. rupiah for IDR).","example":50000},"currency":{"type":"string","description":"ISO 4217 currency code. Defaults to `IDR`.","example":"IDR","default":"IDR"},"provider":{"type":"string","description":"Payment provider to route the payment through.","enum":["XENDIT","MIDTRANS","MAYAR"],"example":"XENDIT"},"xenditPaymentMethod":{"type":"string","description":"Xendit payment method (required when provider is `XENDIT`).","enum":["BCA","BRI","BNI","MANDIRI","PERMATA","CIMB","DANAMON","BSI","OVO","DANA","LINKAJA","SHOPEEPAY","GRABPAY","PAYMAYA","CARD","QRIS"],"example":"BCA"},"midtransPaymentMethod":{"type":"string","description":"Midtrans payment method (required when provider is `MIDTRANS`).","enum":["bank_transfer","credit_card","gopay","shopeepay","qris","dana","indomaret","alfamart","akulaku","kredivo"],"example":"bank_transfer"},"midtransBankCode":{"type":"string","description":"Midtrans bank code. Required when `midtransPaymentMethod` is `bank_transfer`.","enum":["bca","bni","bri","mandiri","permata","cimb","danamon","bsi"],"example":"bca"},"mayarPaymentMethod":{"type":"string","description":"Mayar payment channel (optional when provider is `MAYAR`). When omitted Mayar shows its configured checkout page.","enum":["qris","va/bni","va/bri","va/mandiri","va/cimb","va/permata","va/bjb","va/bsi","ewallet/dana","ewallet/gopay","ewallet/linkaja","ewallet/shopeepay","ewallet/jenius","outlet/alfamart"],"example":"qris"},"mayarExpiredAt":{"type":"string","description":"Mayar invoice expiry in ISO 8601 (UTC).","example":"2026-12-31T23:59:59.000Z"},"customerName":{"type":"string","description":"Customer full name (required by Mayar).","example":"Budi Santoso"},"customerEmail":{"type":"string","description":"Customer email address.","example":"customer@test.com"},"customerPhone":{"type":"string","description":"Customer phone number.","example":"081234567890"},"description":{"type":"string","description":"Human-readable payment description.","example":"Payment for order #12345"},"metadata":{"type":"object","description":"Arbitrary metadata stored with the payment.","additionalProperties":true,"example":{"sku":"ABC-1"}}},"required":["amount","provider"]},"XenditPaymentLinkDto":{"type":"object","properties":{"successRedirectUrl":{"type":"string","description":"URL the customer is redirected to after a successful payment.","example":"https://my-store.com/result?status=success"},"failureRedirectUrl":{"type":"string","description":"URL the customer is redirected to after a failed payment.","example":"https://my-store.com/result?status=failed"},"invoiceDuration":{"type":"number","description":"Invoice duration in seconds (minimum 60).","example":3600}}},"MidtransExpiryDto":{"type":"object","properties":{"duration":{"type":"number","description":"Expiry duration value.","example":24},"unit":{"type":"string","description":"Expiry duration unit.","enum":["minutes","hours","days"],"example":"hours"},"startTime":{"type":"string","description":"Expiry start time (ISO 8601)."}}},"MidtransPaymentLinkDto":{"type":"object","properties":{"enabledPayments":{"description":"Restrict the Snap page to specific payment methods.","example":["gopay","shopeepay"],"type":"array","items":{"type":"string"}},"finishUrl":{"type":"string","description":"Redirect URL after a successful payment."},"unfinishUrl":{"type":"string","description":"Redirect URL when the customer abandons payment."},"errorUrl":{"type":"string","description":"Redirect URL on payment error."},"expiry":{"$ref":"#/components/schemas/MidtransExpiryDto"}}},"MayarInvoiceOptionsDto":{"type":"object","properties":{"expiredAt":{"type":"string","description":"Invoice expiration time in ISO 8601 (UTC). Mayar defaults to its account setting when omitted.","example":"2026-12-31T23:59:59.000Z"},"paymentMethod":{"type":"string","description":"Restrict the invoice to a single Mayar payment channel. Must be enabled in your Mayar payment channel configuration.","enum":["qris","va/bni","va/bri","va/mandiri","va/cimb","va/permata","va/bjb","va/bsi","ewallet/dana","ewallet/gopay","ewallet/linkaja","ewallet/shopeepay","ewallet/jenius","outlet/alfamart"]},"mobile":{"type":"string","description":"Customer mobile number (Mayar requires it).","example":"081234567890"}}},"CreatePaymentLinkDto":{"type":"object","properties":{"applicationOrderId":{"type":"string","description":"Your internal order identifier.","example":"ORDER-12345"},"amount":{"type":"number","description":"Payment amount in the smallest currency unit.","example":50000},"currency":{"type":"string","description":"ISO 4217 currency code. Defaults to `IDR`.","example":"IDR","default":"IDR"},"provider":{"type":"string","description":"Payment provider that hosts the checkout page.","enum":["XENDIT","MIDTRANS","MAYAR"],"example":"MAYAR"},"xenditOptions":{"$ref":"#/components/schemas/XenditPaymentLinkDto"},"midtransOptions":{"$ref":"#/components/schemas/MidtransPaymentLinkDto"},"mayarOptions":{"$ref":"#/components/schemas/MayarInvoiceOptionsDto"},"customerEmail":{"type":"string","description":"Customer email address.","example":"customer@test.com"},"customerPhone":{"type":"string","description":"Customer phone number.","example":"081234567890"},"customerName":{"type":"string","description":"Customer full name.","example":"Budi Santoso"},"description":{"type":"string","description":"Human-readable description of the payment link."},"successRedirectUrl":{"type":"string","description":"Redirect URL after a successful payment. Must be an absolute http(s) URL. Used by Xendit and Midtrans only — Mayar invoices do not support redirect URLs.","example":"https://my-store.com/result?status=success"},"failureRedirectUrl":{"type":"string","description":"Redirect URL after a failed payment. Must be an absolute http(s) URL. Used by Xendit and Midtrans only — Mayar invoices do not support redirect URLs.","example":"https://my-store.com/result?status=failed"},"metadata":{"type":"object","description":"Arbitrary metadata stored with the payment.","additionalProperties":true,"example":{"sku":"ABC-1"}}},"required":["amount","provider"]},"XenditCardDetailsDto":{"type":"object","properties":{"cardNumber":{"type":"string","description":"Card number.","example":"4000000000000002"},"expiryMonth":{"type":"string","description":"Card expiry month.","example":"12"},"expiryYear":{"type":"string","description":"Card expiry year.","example":"2026"},"cvn":{"type":"string","description":"Card verification number.","example":"123"},"cardholderFirstName":{"type":"string","description":"Cardholder first name."},"cardholderLastName":{"type":"string","description":"Cardholder last name."},"cardholderEmail":{"type":"string","description":"Cardholder email."}},"required":["cardNumber","expiryMonth","expiryYear","cvn"]},"XenditChannelPropertiesDto":{"type":"object","properties":{"cardDetails":{"$ref":"#/components/schemas/XenditCardDetailsDto"},"initiateAuthentication":{"type":"string","description":"Whether to initiate 3DS authentication."}},"required":["cardDetails"]},"XenditCustomerDto":{"type":"object","properties":{"referenceId":{"type":"string","description":"Your customer reference id."},"type":{"type":"string","description":"Customer type."},"givenNames":{"type":"string","description":"Customer given names."},"surname":{"type":"string","description":"Customer surname."},"email":{"type":"string","description":"Customer email."},"mobileNumber":{"type":"string","description":"Customer mobile number."}}},"SavePaymentMethodDto":{"type":"object","properties":{"provider":{"type":"string","description":"Payment provider. Only Xendit and Midtrans support saving.","enum":["XENDIT","MIDTRANS","MAYAR"]},"xenditChannelProperties":{"$ref":"#/components/schemas/XenditChannelPropertiesDto"},"customer":{"$ref":"#/components/schemas/XenditCustomerDto"},"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code."},"currency":{"type":"string","description":"ISO 4217 currency code."},"midtransPaymentMethod":{"type":"string","description":"Midtrans payment method.","enum":["bank_transfer","credit_card","gopay","shopeepay","qris","dana","indomaret","alfamart","akulaku","kredivo"]},"cardNumber":{"type":"string","description":"Card number (Midtrans card register)."},"cardExpMonth":{"type":"string","description":"Card expiry month (Midtrans)."},"cardExpYear":{"type":"string","description":"Card expiry year (Midtrans)."}},"required":["provider"]},"PaymentCallbackDto":{"type":"object","properties":{"external_id":{"type":"string","description":"Xendit external id."},"order_id":{"type":"string","description":"Midtrans order id."},"status":{"type":"string","description":"Generic status field."},"transaction_status":{"type":"string","description":"Midtrans transaction status."},"amount":{"type":"number","description":"Callback amount."},"payment_type":{"type":"string","description":"Payment type."},"status_code":{"type":"string","description":"Midtrans status code."},"gross_amount":{"type":"string","description":"Midtrans gross amount."},"signature_key":{"type":"string","description":"Midtrans SHA256 signature key."},"event":{"type":"string","description":"Mayar webhook event name.","example":"payment.received"},"data":{"type":"object","description":"Mayar webhook data payload.","additionalProperties":true},"metadata":{"type":"object","description":"Additional metadata."}}},"CreateSubscriptionDto":{"type":"object","properties":{"applicationSubscriptionId":{"type":"string","description":"Your internal subscription identifier.","example":"SUB-12345"},"amount":{"type":"number","description":"Recurring amount in the smallest currency unit.","example":50000},"currency":{"type":"string","description":"ISO 4217 currency code. Defaults to `IDR`.","default":"IDR"},"provider":{"type":"string","description":"Subscription provider.","enum":["XENDIT","MIDTRANS"],"example":"XENDIT"},"customerEmail":{"type":"string","description":"Customer email address."},"customerPhone":{"type":"string","description":"Customer phone number."},"description":{"type":"string","description":"Subscription description."},"billingCycle":{"type":"string","description":"Billing cycle.","enum":["DAILY","WEEKLY","MONTHLY","YEARLY"],"example":"MONTHLY"},"intervalCount":{"type":"number","description":"Number of cycles per interval.","example":1},"startDate":{"type":"string","description":"Start date (ISO 8601)."},"endDate":{"type":"string","description":"End date (ISO 8601)."},"metadata":{"type":"object","description":"Provider-specific metadata. Xendit requires `pm_id` and `customerId`; Midtrans requires `saved_token_id`.","additionalProperties":true,"example":{"pm_id":"pm-123","customerId":"cust-123"}}},"required":["amount","provider"]},"UpdateSubscriptionDto":{"type":"object","properties":{"provider":{"type":"string","description":"Subscription provider.","enum":["XENDIT","MIDTRANS"]},"amount":{"type":"number","description":"Updated recurring amount."},"currency":{"type":"string","description":"Updated currency."},"billingCycle":{"type":"string","description":"Updated billing cycle.","enum":["DAILY","WEEKLY","MONTHLY","YEARLY"]},"intervalCount":{"type":"number","description":"Updated interval count."},"endDate":{"type":"string","description":"Updated end date (ISO 8601)."},"metadata":{"type":"object","description":"Updated metadata."}}},"SubscriptionCallbackDto":{"type":"object","properties":{"id":{"type":"string","description":"Generic callback id."},"external_id":{"type":"string","description":"External id."},"subscription_id":{"type":"string","description":"Provider subscription id."},"reference_id":{"type":"string","description":"Reference id."},"status":{"type":"string","description":"Subscription status."},"event":{"type":"string","description":"Provider event name.","example":"recurring.cycle.succeeded"},"transaction_status":{"type":"string","description":"Midtrans transaction status."},"amount":{"type":"number","description":"Callback amount."},"payment_type":{"type":"string","description":"Payment type."},"status_code":{"type":"string","description":"Midtrans status code."},"gross_amount":{"type":"string","description":"Midtrans gross amount."},"signature_key":{"type":"string","description":"Midtrans signature key."},"metadata":{"type":"object","description":"Additional metadata."}}},"AdminLoginDto":{"type":"object","properties":{}},"UpdateProviderDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the provider is enabled for new transactions.","example":false}},"required":["enabled"]}}}}