From a1c2cb946925a8d8e550412bad98f080a6b744a9 Mon Sep 17 00:00:00 2001 From: appscisumup Date: Wed, 2 Sep 2026 22:11:41 +0000 Subject: [PATCH 1/2] chore: synced local 'openapi.json' with remote 'specs/openapi.json' --- openapi.json | 890 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 788 insertions(+), 102 deletions(-) diff --git a/openapi.json b/openapi.json index fcbcfc7..94911e3 100755 --- a/openapi.json +++ b/openapi.json @@ -855,6 +855,451 @@ } } }, + "put": { + "operationId": "ProcessCheckout", + "summary": "Process a checkout", + "description": ":::caution[PCI DSS compliance required]\nWhen you submit raw card details directly to the Checkout API, your systems store, process, or transmit cardholder data and are therefore subject to applicable [PCI DSS requirements](https://www.pcisecuritystandards.org/document_library/). You should only use this integration if your environment is appropriately PCI DSS compliant.\n:::\n\nProcessing a checkout will attempt to charge the provided payment instrument for the amount of the specified checkout resource initiated in the `Create a checkout` endpoint.\n\nFollow this request with `Retrieve a checkout` to confirm its status.", + "tags": [ + "Checkouts" + ], + "security": [ + { + "apiKey": [] + }, + { + "oauth2": [ + "payments", + "checkouts.write" + ] + } + ], + "x-codegen": { + "method_name": "process" + }, + "x-scopes": [ + "payments", + "checkouts.write" + ], + "requestBody": { + "required": true, + "description": "Details of the payment instrument for processing the checkout.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProcessCheckout" + }, + "examples": { + "ProcessCard": { + "description": "Process a checkout with a card", + "value": { + "payment_type": "card", + "installments": 1, + "mandate": { + "type": "recurrent", + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36", + "user_ip": "172.217.169.174" + }, + "card": { + "type": "VISA", + "name": "John Doe", + "number": "1234567890123456", + "expiry_year": "2023", + "expiry_month": "01", + "cvv": "123", + "zip_code": "12345" + } + } + }, + "ProcessToken": { + "description": "Process a checkout with a token", + "value": { + "payment_type": "card", + "installments": 1, + "token": "ba85dfee-c3cf-48a6-84f5-d7d761fbba50", + "customer_id": "MEDKHDTI" + } + }, + "ProcessBoleto": { + "description": "Process a checkout with Boleto", + "value": { + "payment_type": "boleto", + "personal_details": { + "email": "user@example.com", + "first_name": "John", + "last_name": "Doe", + "tax_id": "423.378.593-47", + "address": { + "country": "BR", + "city": "São Paulo", + "line1": "Rua Gilberto Sabino, 215", + "state": "SP", + "postal_code": "05425-020" + } + } + } + }, + "ProcessiDeal": { + "description": "Process a checkout with iDeal", + "value": { + "payment_type": "ideal", + "personal_details": { + "email": "user@example.com", + "first_name": "John", + "last_name": "Doe", + "address": { + "country": "NL" + } + } + } + }, + "ProcessBancontact": { + "description": "Process a checkout with Bancontact", + "value": { + "payment_type": "bancontact", + "personal_details": { + "email": "user@example.com", + "first_name": "John", + "last_name": "Doe", + "address": { + "country": "BE" + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Returns the checkout resource after a processing attempt.", + "content": { + "application/json": { + "schema": { + "title": "Checkout Success", + "description": "Checkout resource returned after a synchronous processing attempt. In addition to the base checkout fields, it can include the resulting transaction identifiers and any newly created payment instrument token.", + "allOf": [ + { + "$ref": "#/components/schemas/Checkout" + }, + { + "type": "object", + "properties": { + "transaction_code": { + "type": "string", + "description": "Transaction code of the successful transaction with which the payment for the checkout is completed.", + "readOnly": true, + "example": "TEENSK4W2K" + }, + "transaction_id": { + "type": "string", + "description": "Unique identifier of the successful transaction that completed payment for the checkout.", + "readOnly": true, + "example": "410fc44a-5956-44e1-b5cc-19c6f8d727a4" + }, + "merchant_name": { + "type": "string", + "description": "Name of the merchant.", + "example": "Sample Merchant" + }, + "redirect_url": { + "type": "string", + "example": "https://mysite.com/completed_purchase", + "description": "URL where the payer is redirected after a redirect-based payment or SCA flow completes." + }, + "payment_instrument": { + "type": "object", + "description": "Details of the saved payment instrument created or reused during checkout processing.", + "properties": { + "token": { + "type": "string", + "description": "Unique token of the saved payment instrument.", + "example": "e76d7e5c-9375-4fac-a7e7-b19dc5302fbc" + } + } + } + } + } + ] + }, + "examples": { + "CheckoutSuccessCard": { + "description": "Successfully processed checkout with a card", + "value": { + "checkout_reference": "f00a8f74-b05d-4605-bd73-2a901bae5802", + "amount": 10.1, + "currency": "EUR", + "merchant_code": "MH4H92C7", + "description": "Purchase", + "return_url": "http://example.com", + "id": "4e425463-3e1b-431d-83fa-1e51c2925e99", + "status": "PENDING", + "date": "2020-02-29T10:56:56+00:00", + "valid_until": "2020-02-29T10:56:56+00:00", + "customer_id": "831ff8d4cd5958ab5670", + "mandate": { + "type": "recurrent", + "status": "active", + "merchant_code": "MH4H92C7" + }, + "transactions": [ + { + "id": "410fc44a-5956-44e1-b5cc-19c6f8d727a4", + "transaction_code": "TEENSK4W2K", + "amount": 10.1, + "currency": "EUR", + "timestamp": "2020-02-29T10:56:56.876Z", + "status": "SUCCESSFUL", + "payment_type": "ECOM", + "installments_count": 1, + "merchant_code": "MH4H92C7", + "vat_amount": 6, + "tip_amount": 3, + "entry_mode": "CUSTOMER_ENTRY", + "auth_code": "053201" + } + ], + "transaction_code": "TEENSK4W2K", + "transaction_id": "410fc44a-5956-44e1-b5cc-19c6f8d727a4" + } + }, + "CheckoutSuccessToken": { + "description": "Successfully processed checkout with a token", + "value": { + "checkout_reference": "f00a8f74-b05d-4605-bd73-2a901bae5802", + "amount": 10.1, + "currency": "EUR", + "merchant_code": "MH4H92C7", + "description": "Purchase with token", + "id": "4e425463-3e1b-431d-83fa-1e51c2925e99", + "status": "PENDING", + "date": "2020-02-29T10:56:56+00:00", + "transaction_code": "TEENSK4W2K", + "transaction_id": "410fc44a-5956-44e1-b5cc-19c6f8d727a4", + "merchant_name": "Sample Merchant", + "redirect_url": "https://mysite.com/completed_purchase", + "customer_id": "831ff8d4cd5958ab5670", + "payment_instrument": { + "token": "e76d7e5c-9375-4fac-a7e7-b19dc5302fbc" + }, + "transactions": [ + { + "id": "410fc44a-5956-44e1-b5cc-19c6f8d727a4", + "transaction_code": "TEENSK4W2K", + "amount": 10.1, + "currency": "EUR", + "timestamp": "2020-02-29T10:56:56.876Z", + "status": "SUCCESSFUL", + "payment_type": "ECOM", + "installments_count": 1, + "merchant_code": "MH4H92C7", + "vat_amount": 6, + "tip_amount": 3, + "entry_mode": "CUSTOMER_ENTRY", + "auth_code": "053201" + } + ] + } + }, + "CheckoutSuccessBoleto": { + "description": "Successfully processed checkout with Boleto", + "value": { + "checkout_reference": "f00a8f74-b05d-4605-bd73-2a901bae5802", + "amount": 10.1, + "currency": "BRL", + "merchant_code": "MH4H92C7", + "description": "Boleto checkout", + "id": "4e425463-3e1b-431d-83fa-1e51c2925e99", + "status": "PENDING", + "date": "2021-07-06T12:34:02.000+00:00", + "merchant_name": "Sample shop", + "boleto": { + "barcode": "34191090081790614310603072340007886840000000200", + "url": "https://checkouts.sample.com/v0.1/checkouts/2e7a36cc-7897-446b-a966-952ab5f049ea/boleto" + }, + "redirect_url": "https://website.com", + "purpose": "CHECKOUT", + "transactions": [ + { + "id": "debd2986-9852-4e86-8a8e-7ea9c87dd679", + "transaction_code": "TEN3E696NP", + "merchant_code": "MH4H92C9", + "amount": 10.1, + "vat_amount": 6, + "tip_amount": 3, + "currency": "BRL", + "timestamp": "2021-07-06T12:34:16.460+00:00", + "status": "PENDING", + "payment_type": "BOLETO", + "entry_mode": "BOLETO", + "installments_count": 1 + } + ] + } + }, + "CheckoutSuccessiDeal": { + "description": "Successfully processed checkout with iDeal", + "value": { + "next_step": { + "url": "https://r3.girogate.de/ti/simideal", + "method": "GET", + "payload": { + "tx": "961473700", + "rs": "ILnaUeQTKJ184fVrjGILrLjePX9E4rmz", + "cs": "c8bc0ea231f8372431ca22d6f8319f8de0263d0b1705759ed27155f245f193c5" + }, + "full": "https://r3.girogate.de/ti/simideal?tx=961473700\u0026rs=ILnaUeQTKJ184fVrjGILrLjePX9E4rmz\u0026cs=c8bc0ea231f8372431ca22d6f8319f8de0263d0b1705759ed27155f245f193c5", + "mechanism": [ + "browser" + ] + } + } + }, + "CheckoutSuccessBancontact": { + "description": "Successfully processed checkout with Bancontact", + "value": { + "next_step": { + "url": "https://r3.girogate.de/ti/simbcmc", + "method": "GET", + "payload": { + "tx": "624788471", + "rs": "5MioXoKt2Gwj9dLgqAX1bMRBuT5xTSdB", + "cs": "697edacdd9175f3f99542500fa0ff08280b66aaff3c2641a2e212e4b039473cc" + }, + "full": "https://r3.girogate.de/ti/simbcmc?tx=624788471\u0026rs=5MioXoKt2Gwj9dLgqAX1bMRBuT5xTSdB\u0026cs=697edacdd9175f3f99542500fa0ff08280b66aaff3c2641a2e212e4b039473cc", + "mechanism": [ + "browser" + ] + } + } + } + } + } + } + }, + "202": { + "description": "Returns the next required action for asynchronous checkout processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CheckoutAccepted" + } + } + } + }, + "400": { + "description": "The request body is invalid for processing the checkout.", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/ErrorExtended" + }, + { + "type": "array", + "description": "List of error messages.", + "items": { + "$ref": "#/components/schemas/ErrorExtended" + } + } + ] + }, + "examples": { + "Invalid_Parameter": { + "description": "A required parameter has an invalid value.", + "value": { + "message": "Validation error", + "error_code": "INVALID", + "param": "card.expiry_year" + } + }, + "Multiple_Invalid_Parameters": { + "description": "Multiple required parameters have invalid values.", + "value": [ + { + "error_code": "INVALID", + "message": "Validation error", + "param": "card.name" + }, + { + "error_code": "INVALID", + "message": "Validation error", + "param": "card.number" + }, + { + "error_code": "INVALID", + "message": "Validation error", + "param": "card.expiry_year" + } + ] + } + } + } + } + }, + "401": { + "description": "The request is not authorized.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Problem" + }, + "examples": { + "Problem_Details": { + "description": "Unauthorized response returned by API gateway.", + "value": { + "detail": "Unauthorized.", + "status": 401, + "title": "Unauthorized", + "trace_id": "3c77294349d3b5647ea2d990f0d8f017", + "type": "https://developer.sumup.com/problem/unauthorized" + } + } + } + } + } + }, + "404": { + "description": "The requested resource does not exist.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Not_Found": { + "description": "The identified resource is not found on the server.", + "value": { + "error_code": "NOT_FOUND", + "message": "Resource not found" + } + } + } + } + } + }, + "409": { + "description": "The request conflicts with the current state of the resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Checkout_Processed": { + "description": "The identified checkout resource is already processed.", + "value": { + "error_code": "CHECKOUT_PROCESSED", + "message": "Checkout is already processed" + } + } + } + } + } + } + } + }, "delete": { "operationId": "DeactivateCheckout", "summary": "Deactivate a checkout", @@ -2625,7 +3070,8 @@ }, { "oauth2": [ - "receipts.read" + "receipts.read", + "transactions.history" ] } ], @@ -2633,7 +3079,8 @@ "method_name": "get" }, "x-scopes": [ - "receipts.read" + "receipts.read", + "transactions.history" ], "parameters": [ { @@ -3154,6 +3601,19 @@ "example": "245b2ead-85bf-45ff-856f-311a88a5d454" } }, + { + "name": "user.type", + "in": "query", + "description": "Filter the returned members by user type. Repeat this parameter to include multiple user types.", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserType" + } + }, + "style": "form", + "explode": true + }, { "name": "status", "in": "query", @@ -4335,31 +4795,8 @@ "operationId": "GetMerchant", "summary": "Get Merchant", "description": "Returns a Merchant for a valid Merchant code.", - "tags": [ - "Merchants" - ], - "parameters": [ - { - "name": "version", - "description": "The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource.\n", - "in": "query", - "schema": { - "type": "string", - "examples": [ - "latest" - ] - } - }, - { - "name": "merchant_code", - "description": "Short unique identifier for the merchant.", - "in": "path", - "required": true, - "schema": { - "type": "string", - "example": "MK10CL2A" - } - } + "tags": [ + "Merchants" ], "externalDocs": { "description": "Merchant documentation", @@ -4407,29 +4844,8 @@ } } } - } - } - }, - "/v1/merchants/{merchant_code}/persons": { - "get": { - "operationId": "ListPersons", - "summary": "List Persons", - "description": "Returns the Persons related to a Merchant.", - "tags": [ - "Merchants" - ], + }, "parameters": [ - { - "name": "version", - "description": "The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource.\n", - "in": "query", - "schema": { - "type": "string", - "examples": [ - "latest" - ] - } - }, { "name": "merchant_code", "description": "Short unique identifier for the merchant.", @@ -4440,6 +4856,16 @@ "example": "MK10CL2A" } } + ] + } + }, + "/v1/merchants/{merchant_code}/persons": { + "get": { + "operationId": "ListPersons", + "summary": "List Persons", + "description": "Returns the Persons related to a Merchant.", + "tags": [ + "Merchants" ], "externalDocs": { "description": "Persons documentation", @@ -4487,29 +4913,8 @@ } } } - } - } - }, - "/v1/merchants/{merchant_code}/persons/{person_id}": { - "get": { - "operationId": "GetPerson", - "summary": "Get Person", - "description": "Returns a single Person related to a Merchant.", - "tags": [ - "Merchants" - ], + }, "parameters": [ - { - "name": "version", - "description": "The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource.\n", - "in": "query", - "schema": { - "type": "string", - "examples": [ - "latest" - ] - } - }, { "name": "merchant_code", "description": "Short unique identifier for the merchant.", @@ -4519,21 +4924,17 @@ "type": "string", "example": "MK10CL2A" } - }, - { - "name": "person_id", - "description": "Person ID", - "in": "path", - "required": true, - "schema": { - "type": "string", - "example": "pers_5AKFHN2KSK8D3TS79DJE3P3A2Z", - "x-go-type": "merchants.PersonID", - "x-go-type-import": { - "path": "github.com/sumup/merchants/internal/domain/merchants" - } - } } + ] + } + }, + "/v1/merchants/{merchant_code}/persons/{person_id}": { + "get": { + "operationId": "GetPerson", + "summary": "Get Person", + "description": "Returns a single Person related to a Merchant.", + "tags": [ + "Merchants" ], "externalDocs": { "description": "Persons documentation", @@ -4581,7 +4982,29 @@ } } } - } + }, + "parameters": [ + { + "name": "merchant_code", + "description": "Short unique identifier for the merchant.", + "in": "path", + "required": true, + "schema": { + "type": "string", + "example": "MK10CL2A" + } + }, + { + "name": "person_id", + "description": "Person ID", + "in": "path", + "required": true, + "schema": { + "type": "string", + "example": "pers_5AKFHN2KSK8D3TS79DJE3P3A2Z" + } + } + ] } }, "/v0.1/merchants/{merchant_code}/readers": { @@ -5744,6 +6167,68 @@ } } }, + "Card": { + "title": "Card", + "type": "object", + "description": "__Required when payment type is `card`.__ Details of the payment card.", + "properties": { + "name": { + "type": "string", + "description": "Name of the cardholder as it appears on the payment card.", + "writeOnly": true, + "example": "FIRSTNAME LASTNAME" + }, + "number": { + "type": "string", + "description": "Number of the payment card (without spaces).", + "writeOnly": true, + "example": "1234567890123456" + }, + "expiry_year": { + "type": "string", + "description": "Two- or four-digit expiration year in `YY` or `YYYY` format.", + "writeOnly": true, + "pattern": "^[0-9]{2}([0-9]{2})?$", + "example": "2030" + }, + "expiry_month": { + "type": "string", + "description": "Two-digit expiration month, from `01` through `12`.", + "writeOnly": true, + "minLength": 2, + "maxLength": 2, + "pattern": "^(0[1-9]|1[0-2])$", + "example": "12" + }, + "cvv": { + "type": "string", + "description": "Three or four-digit card verification value (security code) of the payment card.", + "writeOnly": true, + "maxLength": 4, + "minLength": 3, + "example": "123" + }, + "zip_code": { + "type": "string", + "description": "Required five-digit ZIP code. Applicable only to merchant users in the USA.", + "writeOnly": true, + "maxLength": 5, + "minLength": 5, + "example": "12345" + }, + "type": { + "$ref": "#/components/schemas/CardType" + } + }, + "required": [ + "name", + "number", + "expiry_month", + "expiry_year", + "cvv", + "type" + ] + }, "CardResponse": { "title": "Card Response", "type": "object", @@ -5958,7 +6443,7 @@ "properties": { "checkout_reference": { "type": "string", - "maxLength": 90, + "maxLength": 64, "description": "Merchant-defined reference for the new checkout. It should be unique enough for you to identify the payment attempt in your own systems.", "example": "f00a8f74-b05d-4605-bd73-2a901bae5802" }, @@ -6063,6 +6548,100 @@ } } }, + "ProcessCheckout": { + "title": "Process Checkout", + "type": "object", + "description": "Request body for attempting payment on an existing checkout. The required companion fields depend on the selected `payment_type`, for example card details, saved-card data, or payer information required by a specific payment method.", + "properties": { + "payment_type": { + "type": "string", + "description": "Payment method used for this processing attempt. It determines which additional request fields are required.", + "enum": [ + "card", + "boleto", + "ideal", + "blik", + "bancontact", + "google_pay", + "apple_pay" + ], + "example": "card" + }, + "installments": { + "type": "integer", + "description": "Number of installments for deferred payments. Available only to merchant users in Brazil.", + "minimum": 1, + "maximum": 12, + "example": 1 + }, + "mandate": { + "$ref": "#/components/schemas/MandatePayload" + }, + "card": { + "$ref": "#/components/schemas/Card" + }, + "google_pay": { + "type": "object", + "description": "Raw `PaymentData` object received from Google Pay. Send the Google Pay response payload as-is.", + "example": { + "apiVersionMinor": 0, + "apiVersion": 2, + "paymentMethodData": { + "description": "Visa •••• 1111", + "tokenizationData": { + "type": "PAYMENT_GATEWAY", + "token": "token-data" + }, + "type": "CARD", + "info": { + "cardNetwork": "VISA", + "cardDetails": "1111" + } + } + } + }, + "apple_pay": { + "type": "object", + "description": "Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is.", + "example": { + "token": { + "paymentData": { + "data": "si2xuT2ArQo689SfE-long-token", + "signature": "MIAGCSqGSIb3DQEHA-long-signature", + "header": { + "publicKeyHash": "PWfjDi3TSwgZ20TY/A7f3V6J/1rhHyRDCspbeljM0io=", + "ephemeralPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaBtz7UN2MNV0qInJVEEhXy10PU0KfO6KxFjXm93oKWL6lCsxZZGDl/EKioUHVSlKgpsKGin0xvgldfxeJVgy0g==", + "transactionId": "62e0568bc9258e9d0e059d745650fc8211d05ef7a7a1589a6411bf9b12cdfd04" + }, + "version": "EC_v1" + }, + "paymentMethod": { + "displayName": "MasterCard 8837", + "network": "MasterCard", + "type": "debit" + }, + "transactionIdentifier": "62E0568BC9258E9D0E059D745650FC8211D05EF7A7A1589A6411BF9B12CDFD04" + } + } + }, + "token": { + "type": "string", + "description": "Saved-card token to use instead of raw card details when processing with a previously stored payment instrument.", + "example": "ba85dfee-c3cf-48a6-84f5-d7d761fbba50" + }, + "customer_id": { + "type": "string", + "description": "Customer identifier associated with the saved payment instrument. Required when `token` is provided.", + "example": "MEDKHDTI" + }, + "personal_details": { + "$ref": "#/components/schemas/PersonalDetails" + } + }, + "required": [ + "payment_type" + ] + }, "CheckoutSuccess": { "title": "Checkout Success", "description": "Checkout resource returned after a synchronous processing attempt. In addition to the base checkout fields, it can include the resulting transaction identifiers and any newly created payment instrument token.", @@ -6110,6 +6689,60 @@ } ] }, + "CheckoutAccepted": { + "title": "Checkout Accepted", + "type": "object", + "description": "Response returned when checkout processing requires an additional payer action, such as a 3DS challenge or a redirect to an external payment method page.", + "properties": { + "next_step": { + "type": "object", + "description": "Instructions for the next action the payer or client must take.", + "properties": { + "url": { + "type": "string", + "example": "https://dummy-3ds-gateway.com/cap?RID=1233\u0026VAA=A", + "description": "URL to open or submit in order to continue processing." + }, + "method": { + "type": "string", + "example": "POST", + "description": "HTTP method to use when following the next step." + }, + "redirect_url": { + "type": "string", + "example": "https://mysite.com/completed_purchase", + "description": "Merchant URL where the payer returns after the external flow finishes." + }, + "mechanism": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "iframe", + "browser" + ] + }, + "description": "Allowed presentation mechanisms for the next step. `iframe` means the flow can be embedded, while `browser` means it can be completed through a full-page redirect.", + "example": [ + "iframe" + ] + }, + "payload": { + "type": "object", + "description": "Parameters required to complete the next step. The exact keys depend on the payment provider and flow type.", + "additionalProperties": { + "type": "string" + }, + "example": { + "PaReq": "eJxVUttu2zAM/RXDr4MjyY5dO6BVuE27FZuDZHGG9VGRmMSFb/Wljff1k9KkF0APPCR1eHQouD6WhfWCbZfXVWyzCbUtrGSt8mof25vs3gltq+tFpURRVxjbI3b2NYfs0CLO1yiHFjmk2HVij1auYrsRW1+F0U4qZxfKwJlur4QTYcQcJoIdc+XO2/poc1gmv/GZw3k216MnLpAL1JytPIiq5yDk883Dgk+DwPV9IGcIJbYPc84o1Ye6lHqu5wVA3tJQiRL5eiiHxlqKscSq76xfeZn3qICciiDroerbkYeuvnYBMLQFP/R9MyOkM9cnCoGYJJAPScvBRJ0mOeaKr/6l08XT6jXN7tx0vvHSbOMtsj1dzB9jIKYDlOiRu1omYyy0WDCj0YxFQE55EKWZzj2f6ee9xdCYEcmnwucEaN9bvaeRR1ehFn9BgMdGr0l3aCvfYyAfem9/GENlrz36ufpTBPTv07r8lm3qpPiOo1y/7u+SJImNzacmw5hrX1wt/kRpABBDQ84bJOf16+jLt/gPhUvGGw==", + "MD": "b1a536c0-29b9-11eb-adc1-0242ac120002", + "TermUrl": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572/complete_payment" + } + } + } + } + } + }, "Customer": { "type": "object", "title": "Customer", @@ -6467,6 +7100,40 @@ "href" ] }, + "MandatePayload": { + "title": "Mandate Payload", + "type": "object", + "description": "Mandate details used when a checkout should create a reusable card token for future recurring or merchant-initiated payments.", + "properties": { + "type": { + "type": "string", + "description": "Type of mandate to create for the saved payment instrument.", + "enum": [ + "recurrent" + ], + "example": "recurrent" + }, + "user_agent": { + "type": "string", + "description": "Browser or client user agent observed when consent was collected.", + "example": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36" + }, + "user_ip": { + "type": "string", + "description": "IP address of the payer when the mandate was accepted.", + "example": "172.217.169.174" + } + }, + "required": [ + "type", + "user_agent" + ], + "example": { + "type": "recurrent", + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36", + "user_ip": "172.217.169.174" + } + }, "MandateResponse": { "title": "Mandate Response", "type": "object", @@ -8248,6 +8915,17 @@ } } }, + "UserType": { + "type": "string", + "description": "Type of the user account.", + "enum": [ + "user", + "managed_user", + "service_account", + "system_account" + ], + "example": "user" + }, "Metadata": { "description": "Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, always submit whole metadata. Maximum of 64 parameters are allowed in the object.", "type": "object", @@ -8261,17 +8939,6 @@ "example": {}, "additionalProperties": true }, - "UserType": { - "type": "string", - "description": "Type of the user account.", - "enum": [ - "user", - "managed_user", - "service_account", - "system_account" - ], - "example": "user" - }, "Address": { "externalDocs": { "description": "Address documentation", @@ -8573,19 +9240,21 @@ "type": "string", "minLength": 1, "maxLength": 30, - "pattern": "^[a-zA-Z0-9 \\-+\\'_.]{0,30}$", + "pattern": "^[a-zA-Z0-9 +'_.-]+$", "description": "The descriptor is the text that your customer sees on their bank account statement.\nThe more recognisable your descriptor is, the less risk you have of receiving disputes (e.g. chargebacks).\n", "example": "Example Coffee" }, "website": { "type": "string", "description": "The business's publicly available website.", + "minLength": 1, "maxLength": 255, "example": "https://example.com" }, "email": { "type": "string", "description": "A publicly available email address.", + "minLength": 1, "maxLength": 255, "example": "contact@example.com" }, @@ -8697,6 +9366,7 @@ "description": "The unique legal type reference as defined in the country SDK. We do not rely on IDs as used by other services. Consumers of this API are expected to use the country SDK to map to any other IDs, translation keys, or descriptions.\n", "minLength": 4, "maxLength": 64, + "pattern": "^[a-z]{2}\\.[a-z_]+$", "examples": [ "de.freiberufler", "br.ltda", @@ -8724,6 +9394,7 @@ "properties": { "ref": { "type": "string", + "pattern": "^[a-z]{2}\\.[a-z_]+$", "description": "The unique reference for the company identifier type as defined in the country SDK.\n", "examples": [ "de.gmbh" @@ -8731,6 +9402,7 @@ }, "value": { "type": "string", + "minLength": 1, "maxLength": 100, "description": "The company identifier value.\n", "examples": [ @@ -8803,24 +9475,27 @@ "type": "string", "format": "date", "description": "The date of birth of the individual, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format.\n", - "example": "1980-01-12T00:00:00Z" + "example": "1980-01-12" }, "given_name": { "type": "string", "description": "The first name(s) of the individual.", "example": "James Herrald", + "minLength": 1, "maxLength": 60 }, "family_name": { "type": "string", "description": "The last name(s) of the individual.", "example": "Bond", + "minLength": 1, "maxLength": 60 }, "middle_name": { "type": "string", "description": "Middle name(s) of the End-User. Note that in some cultures, people can have multiple middle names; all can be present, with the names being separated by space characters. Also note that in some cultures, middle names are not used.\n", "example": "Maria Sophie", + "minLength": 1, "maxLength": 60 }, "phone_number": { @@ -8855,14 +9530,14 @@ }, "nationality": { "type": "string", + "pattern": "^[A-Z]{2}$", "description": "The Person's nationality. May be an [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code, but legacy data may not conform to this standard.\n", "nullable": true }, "country_of_residence": { "type": "string", "description": "An [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code representing the country where the Person resides.\n", - "minLength": 2, - "maxLength": 2, + "pattern": "^[A-Z]{2}$", "nullable": true }, "version": { @@ -8912,6 +9587,7 @@ "website": { "description": "HTTP(S) URL of the company's website.\n", "type": "string", + "minLength": 1, "maxLength": 255, "examples": [ "https://www.sumup.com" @@ -10175,6 +10851,16 @@ } } }, + "CheckoutProcessAccepted": { + "description": "Returns the next required action for asynchronous checkout processing.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CheckoutAccepted" + } + } + } + }, "Customer": { "description": "Returns the customer resource.", "content": { From fd9489a5eb1106bc3a667f84eb99c4a0eb038ebe Mon Sep 17 00:00:00 2001 From: "sumup-release-bot[bot]" <241716704+sumup-release-bot[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:13:07 +0000 Subject: [PATCH 2/2] chore: generate code --- src/Checkouts/Checkouts.php | 37 ++++++ src/Members/Members.php | 10 ++ src/Merchants/Merchants.php | 93 +-------------- src/Types/Card.php | 61 ++++++++++ src/Types/CardType.php | 36 ++++++ src/Types/CheckoutAccepted.php | 19 +++ src/Types/CheckoutAcceptedNextStep.php | 47 ++++++++ src/Types/MandatePayload.php | 33 ++++++ src/Types/MandatePayloadType.php | 13 +++ src/Types/ProcessCheckout.php | 142 +++++++++++++++++++++++ src/Types/ProcessCheckoutPaymentType.php | 19 +++ 11 files changed, 420 insertions(+), 90 deletions(-) create mode 100644 src/Types/Card.php create mode 100644 src/Types/CardType.php create mode 100644 src/Types/CheckoutAccepted.php create mode 100644 src/Types/CheckoutAcceptedNextStep.php create mode 100644 src/Types/MandatePayload.php create mode 100644 src/Types/MandatePayloadType.php create mode 100644 src/Types/ProcessCheckout.php create mode 100644 src/Types/ProcessCheckoutPaymentType.php diff --git a/src/Checkouts/Checkouts.php b/src/Checkouts/Checkouts.php index b5189f1..d854364 100644 --- a/src/Checkouts/Checkouts.php +++ b/src/Checkouts/Checkouts.php @@ -390,6 +390,43 @@ public function listAvailablePaymentMethods(string $merchantCode, ?CheckoutsList ], 'GET', $path); } + /** + * Process a checkout + * + * @param string $checkoutId Unique identifier of the checkout resource. + * @param \SumUp\Types\ProcessCheckout|array $body Required request payload + * @param RequestOptions|null $requestOptions Optional typed request options + * + * @return mixed|\SumUp\Types\CheckoutAccepted + * @throws \SumUp\Exception\ApiException + * @throws \SumUp\Exception\UnexpectedApiException + * @throws \SumUp\Exception\ConnectionException + * @throws \SumUp\Exception\SDKException + */ + public function process(string $checkoutId, \SumUp\Types\ProcessCheckout|array $body, ?RequestOptions $requestOptions = null) + { + $path = sprintf('/v0.1/checkouts/%s', rawurlencode((string) $checkoutId)); + $payload = []; + $requestBody = $body; + if (is_array($requestBody)) { + $requestBody = \SumUp\Types\ProcessCheckout::fromArray($requestBody); + } + $payload = RequestEncoder::encode($requestBody); + $headers = RequestHeaders::build($this->accessToken, $requestOptions); + + $response = $this->client->send('PUT', $path, $payload, $headers, $requestOptions); + + return ResponseDecoder::decodeOrThrow($response, [ + '200' => ['type' => 'mixed'], + '202' => ['type' => 'class', 'class' => \SumUp\Types\CheckoutAccepted::class], + ], [ + '400' => ['type' => 'mixed'], + '401' => ['type' => 'class', 'class' => \SumUp\Types\Problem::class], + '404' => ['type' => 'class', 'class' => \SumUp\Types\Error::class], + '409' => ['type' => 'class', 'class' => \SumUp\Types\Error::class], + ], 'PUT', $path); + } + /** * Update a checkout * diff --git a/src/Members/Members.php b/src/Members/Members.php index 0c59f23..278fc69 100644 --- a/src/Members/Members.php +++ b/src/Members/Members.php @@ -272,6 +272,13 @@ class MembersListParams */ public ?string $userId = null; + /** + * Filter the returned members by user type. Repeat this parameter to include multiple user types. + * + * @var string[]|null + */ + public ?array $userType = null; + /** * Filter the returned members by the membership status. * @@ -446,6 +453,9 @@ public function list(string $merchantCode, ?MembersListParams $queryParams = nul if (isset($queryParams->userId)) { $queryParamsData['user.id'] = $queryParams->userId; } + if (isset($queryParams->userType)) { + $queryParamsData['user.type'] = $queryParams->userType; + } if (isset($queryParams->status)) { $queryParamsData['status'] = $queryParams->status; } diff --git a/src/Merchants/Merchants.php b/src/Merchants/Merchants.php index 47e4f9d..efe362c 100644 --- a/src/Merchants/Merchants.php +++ b/src/Merchants/Merchants.php @@ -11,54 +11,6 @@ use SumUp\HttpClient\RequestOptions; use SumUp\ResponseDecoder; -/** - * Query parameters for MerchantsGetParams. - * - * @package SumUp\Services - */ -class MerchantsGetParams -{ - /** - * The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource. - * - * @var string|null - */ - public ?string $version = null; - -} - -/** - * Query parameters for MerchantsGetPersonParams. - * - * @package SumUp\Services - */ -class MerchantsGetPersonParams -{ - /** - * The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource. - * - * @var string|null - */ - public ?string $version = null; - -} - -/** - * Query parameters for MerchantsListPersonsParams. - * - * @package SumUp\Services - */ -class MerchantsListPersonsParams -{ - /** - * The version of the resource. At the moment, the only supported value is `latest`. When provided and the requested resource's `change_status` is pending, the resource will be returned with all pending changes applied. When no changes are pending the resource is returned as is. The `change_status` in the response body will reflect the current state of the resource. - * - * @var string|null - */ - public ?string $version = null; - -} - /** * Class Merchants * @@ -98,7 +50,6 @@ public function __construct(HttpClientInterface $client, string $accessToken) * Get Merchant * * @param string $merchantCode Short unique identifier for the merchant. - * @param MerchantsGetParams|null $queryParams Optional query string parameters * @param RequestOptions|null $requestOptions Optional typed request options * * @return \SumUp\Types\Merchant @@ -107,21 +58,9 @@ public function __construct(HttpClientInterface $client, string $accessToken) * @throws \SumUp\Exception\ConnectionException * @throws \SumUp\Exception\SDKException */ - public function get(string $merchantCode, ?MerchantsGetParams $queryParams = null, ?RequestOptions $requestOptions = null): \SumUp\Types\Merchant + public function get(string $merchantCode, ?RequestOptions $requestOptions = null): \SumUp\Types\Merchant { $path = sprintf('/v1/merchants/%s', rawurlencode((string) $merchantCode)); - if ($queryParams !== null) { - $queryParamsData = []; - if (isset($queryParams->version)) { - $queryParamsData['version'] = $queryParams->version; - } - if (!empty($queryParamsData)) { - $queryString = http_build_query($queryParamsData); - if (!empty($queryString)) { - $path .= '?' . $queryString; - } - } - } $payload = []; $headers = RequestHeaders::build($this->accessToken, $requestOptions); @@ -137,7 +76,6 @@ public function get(string $merchantCode, ?MerchantsGetParams $queryParams = nul * * @param string $merchantCode Short unique identifier for the merchant. * @param string $personId Person ID - * @param MerchantsGetPersonParams|null $queryParams Optional query string parameters * @param RequestOptions|null $requestOptions Optional typed request options * * @return \SumUp\Types\Person @@ -146,21 +84,9 @@ public function get(string $merchantCode, ?MerchantsGetParams $queryParams = nul * @throws \SumUp\Exception\ConnectionException * @throws \SumUp\Exception\SDKException */ - public function getPerson(string $merchantCode, string $personId, ?MerchantsGetPersonParams $queryParams = null, ?RequestOptions $requestOptions = null): \SumUp\Types\Person + public function getPerson(string $merchantCode, string $personId, ?RequestOptions $requestOptions = null): \SumUp\Types\Person { $path = sprintf('/v1/merchants/%s/persons/%s', rawurlencode((string) $merchantCode), rawurlencode((string) $personId)); - if ($queryParams !== null) { - $queryParamsData = []; - if (isset($queryParams->version)) { - $queryParamsData['version'] = $queryParams->version; - } - if (!empty($queryParamsData)) { - $queryString = http_build_query($queryParamsData); - if (!empty($queryString)) { - $path .= '?' . $queryString; - } - } - } $payload = []; $headers = RequestHeaders::build($this->accessToken, $requestOptions); @@ -175,7 +101,6 @@ public function getPerson(string $merchantCode, string $personId, ?MerchantsGetP * List Persons * * @param string $merchantCode Short unique identifier for the merchant. - * @param MerchantsListPersonsParams|null $queryParams Optional query string parameters * @param RequestOptions|null $requestOptions Optional typed request options * * @return \SumUp\Types\ListPersonsResponseBody @@ -184,21 +109,9 @@ public function getPerson(string $merchantCode, string $personId, ?MerchantsGetP * @throws \SumUp\Exception\ConnectionException * @throws \SumUp\Exception\SDKException */ - public function listPersons(string $merchantCode, ?MerchantsListPersonsParams $queryParams = null, ?RequestOptions $requestOptions = null): \SumUp\Types\ListPersonsResponseBody + public function listPersons(string $merchantCode, ?RequestOptions $requestOptions = null): \SumUp\Types\ListPersonsResponseBody { $path = sprintf('/v1/merchants/%s/persons', rawurlencode((string) $merchantCode)); - if ($queryParams !== null) { - $queryParamsData = []; - if (isset($queryParams->version)) { - $queryParamsData['version'] = $queryParams->version; - } - if (!empty($queryParamsData)) { - $queryString = http_build_query($queryParamsData); - if (!empty($queryString)) { - $path .= '?' . $queryString; - } - } - } $payload = []; $headers = RequestHeaders::build($this->accessToken, $requestOptions); diff --git a/src/Types/Card.php b/src/Types/Card.php new file mode 100644 index 0000000..0bfa761 --- /dev/null +++ b/src/Types/Card.php @@ -0,0 +1,61 @@ +|null + */ + public ?array $payload = null; + +} diff --git a/src/Types/MandatePayload.php b/src/Types/MandatePayload.php new file mode 100644 index 0000000..612cb2f --- /dev/null +++ b/src/Types/MandatePayload.php @@ -0,0 +1,33 @@ +|null + */ + public ?array $googlePay = null; + + /** + * Raw payment token object received from Apple Pay. Send the Apple Pay response payload as-is. + * + * @var array|null + */ + public ?array $applePay = null; + + /** + * Saved-card token to use instead of raw card details when processing with a previously stored payment instrument. + * + * @var string|null + */ + public ?string $token = null; + + /** + * Customer identifier associated with the saved payment instrument. Required when `token` is provided. + * + * @var string|null + */ + public ?string $customerId = null; + + /** + * Personal details for the customer. + * + * @var PersonalDetails|null + */ + public ?PersonalDetails $personalDetails = null; + + /** + * Create request DTO. + * + * @param ProcessCheckoutPaymentType|string $paymentType + * @param int|null $installments + * @param MandatePayload|null $mandate + * @param Card|null $card + * @param array|null $googlePay + * @param array|null $applePay + * @param string|null $token + * @param string|null $customerId + * @param PersonalDetails|null $personalDetails + */ + public function __construct( + ProcessCheckoutPaymentType|string $paymentType, + ?int $installments = null, + ?MandatePayload $mandate = null, + ?Card $card = null, + ?array $googlePay = null, + ?array $applePay = null, + ?string $token = null, + ?string $customerId = null, + ?PersonalDetails $personalDetails = null + ) { + \SumUp\Hydrator::hydrate([ + 'payment_type' => $paymentType, + 'installments' => $installments, + 'mandate' => $mandate, + 'card' => $card, + 'google_pay' => $googlePay, + 'apple_pay' => $applePay, + 'token' => $token, + 'customer_id' => $customerId, + 'personal_details' => $personalDetails, + ], self::class, $this); + } + + /** + * Create request DTO from an associative array. + * + * @param array $data + */ + public static function fromArray(array $data): self + { + self::assertRequiredFields($data, [ + 'payment_type' => 'paymentType', + ]); + + $request = (new \ReflectionClass(self::class))->newInstanceWithoutConstructor(); + \SumUp\Hydrator::hydrate($data, self::class, $request); + + return $request; + } + + /** + * @param array $data + * @param array $requiredFields + */ + private static function assertRequiredFields(array $data, array $requiredFields): void + { + foreach ($requiredFields as $serializedName => $propertyName) { + if (!array_key_exists($serializedName, $data) && !array_key_exists($propertyName, $data)) { + throw new \InvalidArgumentException(sprintf('Missing required field "%s".', $serializedName)); + } + } + } + +} diff --git a/src/Types/ProcessCheckoutPaymentType.php b/src/Types/ProcessCheckoutPaymentType.php new file mode 100644 index 0000000..a65b2dc --- /dev/null +++ b/src/Types/ProcessCheckoutPaymentType.php @@ -0,0 +1,19 @@ +