diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 2ef30449b3bb..c3df343caed4 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -8270,31 +8270,34 @@ } } }, - "EphemeralKeyCreateResponse": { + "EphemeralKeyResponse": { "type": "object", "description": "ephemeral_key for the customer_id mentioned", "required": [ - "customer_id", + "id", + "resource_id", "created_at", "expires", "secret" ], "properties": { - "customer_id": { + "id": { "type": "string", - "description": "customer_id to which this ephemeral key belongs to", - "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", - "maxLength": 64, + "description": "Ephemeral key id", + "maxLength": 32, "minLength": 1 }, + "resource_id": { + "$ref": "#/components/schemas/ResourceId" + }, "created_at": { - "type": "integer", - "format": "int64", + "type": "string", + "format": "date-time", "description": "time at which this ephemeral key was created" }, "expires": { - "type": "integer", - "format": "int64", + "type": "string", + "format": "date-time", "description": "time at which this ephemeral key would expire" }, "secret": { @@ -12134,7 +12137,7 @@ ] }, "object": { - "$ref": "#/components/schemas/PaymentsResponse" + "$ref": "#/components/schemas/PaymentsRetrieveResponse" } } }, @@ -13164,26 +13167,6 @@ }, "additionalProperties": false }, - "PaymentListResponse": { - "type": "object", - "required": [ - "size", - "data" - ], - "properties": { - "size": { - "type": "integer", - "description": "The number of payments included in the list", - "minimum": 0 - }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentsResponse" - } - } - } - }, "PaymentMethod": { "type": "string", "description": "Indicates the type of payment method. Eg: 'card', 'wallet', etc.", @@ -14806,1278 +14789,294 @@ }, "additionalProperties": false }, - "PaymentsCreateResponseOpenApi": { + "PaymentsDynamicTaxCalculationRequest": { "type": "object", "required": [ - "payment_id", - "merchant_id", - "status", - "amount", - "net_amount", - "amount_capturable", - "currency", - "payment_method", - "attempt_count" + "shipping", + "client_secret", + "payment_method_type" ], "properties": { - "payment_id": { - "type": "string", - "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", - "example": "pay_mbabizu24mvu3mela5njyhpit4", - "maxLength": 30, - "minLength": 30 - }, - "merchant_id": { - "type": "string", - "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", - "example": "merchant_1668273825", - "maxLength": 255 - }, - "status": { - "allOf": [ - { - "$ref": "#/components/schemas/IntentStatus" - } - ], - "default": "requires_confirmation" - }, - "amount": { - "type": "integer", - "format": "int64", - "description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,", - "example": 6540 - }, - "net_amount": { - "type": "integer", - "format": "int64", - "description": "The payment net amount. net_amount = amount + surcharge_details.surcharge_amount + surcharge_details.tax_amount + shipping_cost + order_tax_amount,\nIf no surcharge_details, shipping_cost, order_tax_amount, net_amount = amount", - "example": 6540 - }, - "shipping_cost": { - "type": "integer", - "format": "int64", - "description": "The shipping cost for the payment.", - "example": 6540, - "nullable": true - }, - "amount_capturable": { - "type": "integer", - "format": "int64", - "description": "The maximum amount that could be captured from the payment", - "example": 6540, - "minimum": 100 - }, - "amount_received": { - "type": "integer", - "format": "int64", - "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540, - "nullable": true - }, - "connector": { - "type": "string", - "description": "The connector used for the payment", - "example": "stripe", - "nullable": true + "shipping": { + "$ref": "#/components/schemas/Address" }, "client_secret": { "type": "string", - "description": "It's a token used for client side verification.", - "example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo", - "nullable": true - }, - "created": { - "type": "string", - "format": "date-time", - "description": "Time when the payment was created", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "currency": { - "$ref": "#/components/schemas/Currency" + "description": "Client Secret" }, - "customer_id": { - "type": "string", - "description": "The identifier for the customer object. If not provided the customer ID will be autogenerated.\nThis field will be deprecated soon. Please refer to `customer.id`", - "deprecated": true, - "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", - "nullable": true, - "maxLength": 64, - "minLength": 1 + "payment_method_type": { + "$ref": "#/components/schemas/PaymentMethodType" }, - "description": { + "session_id": { "type": "string", - "description": "A description of the payment", - "example": "It's my first payment request", - "nullable": true - }, - "refunds": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RefundResponse" - }, - "description": "List of refunds that happened on this intent, as same payment intent can have multiple refund requests depending on the nature of order", - "nullable": true - }, - "disputes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DisputeResponsePaymentsRetrieve" - }, - "description": "List of disputes that happened on this intent", - "nullable": true - }, - "attempts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentAttemptResponse" - }, - "description": "List of attempts that happened on this intent", - "nullable": true - }, - "captures": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CaptureResponse" - }, - "description": "List of captures done on latest attempt", + "description": "Session Id", "nullable": true - }, - "mandate_id": { + } + } + }, + "PaymentsDynamicTaxCalculationResponse": { + "type": "object", + "required": [ + "payment_id", + "net_amount", + "display_amount" + ], + "properties": { + "payment_id": { "type": "string", - "description": "A unique identifier to link the payment to a mandate, can be used instead of payment_method_data, in case of setting up recurring payments", - "example": "mandate_iwer89rnjef349dni3", - "nullable": true, - "maxLength": 255 + "description": "The identifier for the payment" }, - "mandate_data": { + "net_amount": { + "$ref": "#/components/schemas/MinorUnit" + }, + "order_tax_amount": { "allOf": [ { - "$ref": "#/components/schemas/MandateData" + "$ref": "#/components/schemas/MinorUnit" } ], "nullable": true }, - "setup_future_usage": { + "shipping_cost": { "allOf": [ { - "$ref": "#/components/schemas/FutureUsage" + "$ref": "#/components/schemas/MinorUnit" } ], "nullable": true }, - "off_session": { - "type": "boolean", - "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with confirm=true.", - "example": true, - "nullable": true + "display_amount": { + "$ref": "#/components/schemas/DisplayAmountOnSdk" + } + } + }, + "PaymentsExternalAuthenticationRequest": { + "type": "object", + "required": [ + "client_secret", + "device_channel", + "threeds_method_comp_ind" + ], + "properties": { + "client_secret": { + "type": "string", + "description": "Client Secret" }, - "capture_method": { + "sdk_information": { "allOf": [ { - "$ref": "#/components/schemas/CaptureMethod" + "$ref": "#/components/schemas/SdkInformation" } ], "nullable": true }, - "payment_method": { - "$ref": "#/components/schemas/PaymentMethod" + "device_channel": { + "$ref": "#/components/schemas/DeviceChannel" }, - "payment_method_data": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentMethodDataResponseWithBilling" - } - ], - "nullable": true + "threeds_method_comp_ind": { + "$ref": "#/components/schemas/ThreeDsCompletionIndicator" + } + } + }, + "PaymentsExternalAuthenticationResponse": { + "type": "object", + "required": [ + "trans_status", + "three_ds_requestor_url" + ], + "properties": { + "trans_status": { + "$ref": "#/components/schemas/TransactionStatus" }, - "payment_token": { + "acs_url": { "type": "string", - "description": "Provide a reference to a stored payment method", - "example": "187282ab-40ef-47a9-9206-5099ba31e432", + "description": "Access Server URL to be used for challenge submission", "nullable": true }, - "shipping": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], + "challenge_request": { + "type": "string", + "description": "Challenge request which should be sent to acs_url", "nullable": true }, - "billing": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], + "acs_reference_number": { + "type": "string", + "description": "Unique identifier assigned by the EMVCo(Europay, Mastercard and Visa)", "nullable": true }, - "order_details": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OrderDetailsWithAmount" - }, - "description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)", - "example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n }]", + "acs_trans_id": { + "type": "string", + "description": "Unique identifier assigned by the ACS to identify a single transaction", "nullable": true }, - "email": { - "type": "string", - "description": "description: The customer's email address\nThis field will be deprecated soon. Please refer to `customer.email` object", - "deprecated": true, - "example": "johntest@test.com", - "nullable": true, - "maxLength": 255 - }, - "name": { - "type": "string", - "description": "description: The customer's name\nThis field will be deprecated soon. Please refer to `customer.name` object", - "deprecated": true, - "example": "John Test", - "nullable": true, - "maxLength": 255 - }, - "phone": { - "type": "string", - "description": "The customer's phone number\nThis field will be deprecated soon. Please refer to `customer.phone` object", - "deprecated": true, - "example": "9123456789", - "nullable": true, - "maxLength": 255 - }, - "return_url": { - "type": "string", - "description": "The URL to redirect after the completion of the operation", - "example": "https://hyperswitch.io", - "nullable": true - }, - "authentication_type": { - "allOf": [ - { - "$ref": "#/components/schemas/AuthenticationType" - } - ], - "default": "three_ds", - "nullable": true - }, - "statement_descriptor_name": { - "type": "string", - "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", - "example": "Hyperswitch Router", - "nullable": true, - "maxLength": 255 - }, - "statement_descriptor_suffix": { - "type": "string", - "description": "Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 255 characters for the concatenated descriptor.", - "example": "Payment for shoes purchase", - "nullable": true, - "maxLength": 255 - }, - "next_action": { - "allOf": [ - { - "$ref": "#/components/schemas/NextActionData" - } - ], - "nullable": true - }, - "cancellation_reason": { - "type": "string", - "description": "If the payment was cancelled the reason will be provided here", - "nullable": true - }, - "error_code": { - "type": "string", - "description": "If there was an error while calling the connectors the code is received here", - "example": "E0001", - "nullable": true - }, - "error_message": { - "type": "string", - "description": "If there was an error while calling the connector the error message is received here", - "example": "Failed while verifying the card", - "nullable": true - }, - "payment_experience": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentExperience" - } - ], - "nullable": true - }, - "payment_method_type": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentMethodType" - } - ], - "nullable": true - }, - "connector_label": { - "type": "string", - "description": "The connector used for this payment along with the country and business details", - "example": "stripe_US_food", - "nullable": true - }, - "business_country": { - "allOf": [ - { - "$ref": "#/components/schemas/CountryAlpha2" - } - ], - "nullable": true - }, - "business_label": { - "type": "string", - "description": "The business label of merchant for this payment", - "nullable": true - }, - "business_sub_label": { - "type": "string", - "description": "The business_sub_label for this payment", - "nullable": true - }, - "allowed_payment_method_types": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentMethodType" - }, - "description": "Allowed Payment Method Types for a given PaymentIntent", - "nullable": true - }, - "ephemeral_key": { - "allOf": [ - { - "$ref": "#/components/schemas/EphemeralKeyCreateResponse" - } - ], - "nullable": true - }, - "manual_retry_allowed": { - "type": "boolean", - "description": "If true the payment can be retried with same or different payment method which means the confirm call can be made again.", - "nullable": true - }, - "connector_transaction_id": { - "type": "string", - "description": "A unique identifier for a payment provided by the connector", - "example": "993672945374576J", - "nullable": true - }, - "frm_message": { - "allOf": [ - { - "$ref": "#/components/schemas/FrmMessage" - } - ], - "nullable": true - }, - "metadata": { - "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", - "nullable": true - }, - "connector_metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/ConnectorMetadata" - } - ], - "nullable": true - }, - "feature_metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/FeatureMetadata" - } - ], - "nullable": true - }, - "reference_id": { - "type": "string", - "description": "reference(Identifier) to the payment at connector side", - "example": "993672945374576J", - "nullable": true - }, - "payment_link": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentLinkResponse" - } - ], - "nullable": true - }, - "profile_id": { - "type": "string", - "description": "The business profile that is associated with this payment", - "nullable": true - }, - "surcharge_details": { - "allOf": [ - { - "$ref": "#/components/schemas/RequestSurchargeDetails" - } - ], - "nullable": true - }, - "attempt_count": { - "type": "integer", - "format": "int32", - "description": "Total number of attempts associated with this payment" - }, - "merchant_decision": { - "type": "string", - "description": "Denotes the action(approve or reject) taken by merchant in case of manual review. Manual review can occur when the transaction is marked as risky by the frm_processor, payment processor or when there is underpayment/over payment incase of crypto payment", - "nullable": true - }, - "merchant_connector_id": { - "type": "string", - "description": "Identifier of the connector ( merchant connector account ) which was chosen to make the payment", - "nullable": true - }, - "incremental_authorization_allowed": { - "type": "boolean", - "description": "If true, incremental authorization can be performed on this payment, in case the funds authorized initially fall short.", - "nullable": true - }, - "authorization_count": { - "type": "integer", - "format": "int32", - "description": "Total number of authorizations happened in an incremental_authorization payment", - "nullable": true - }, - "incremental_authorizations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncrementalAuthorizationResponse" - }, - "description": "List of incremental authorizations happened to the payment", - "nullable": true - }, - "external_authentication_details": { - "allOf": [ - { - "$ref": "#/components/schemas/ExternalAuthenticationDetailsResponse" - } - ], - "nullable": true - }, - "external_3ds_authentication_attempted": { - "type": "boolean", - "description": "Flag indicating if external 3ds authentication is made or not", - "nullable": true - }, - "expires_on": { - "type": "string", - "format": "date-time", - "description": "Date Time for expiry of the payment", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "fingerprint": { - "type": "string", - "description": "Payment Fingerprint, to identify a particular card.\nIt is a 20 character long alphanumeric code.", - "nullable": true - }, - "browser_info": { - "allOf": [ - { - "$ref": "#/components/schemas/BrowserInformation" - } - ], - "nullable": true - }, - "payment_method_id": { - "type": "string", - "description": "Identifier for Payment Method used for the payment", - "nullable": true - }, - "payment_method_status": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentMethodStatus" - } - ], - "nullable": true - }, - "updated": { - "type": "string", - "format": "date-time", - "description": "Date time at which payment was updated", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "split_payments": { - "allOf": [ - { - "$ref": "#/components/schemas/SplitPaymentsResponse" - } - ], - "nullable": true - }, - "frm_metadata": { - "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. FRM Metadata is useful for storing additional, structured information on an object related to FRM.", - "nullable": true - }, - "merchant_order_reference_id": { - "type": "string", - "description": "Merchant's identifier for the payment/invoice. This will be sent to the connector\nif the connector provides support to accept multiple reference ids.\nIn case the connector supports only one reference id, Hyperswitch's Payment ID will be sent as reference.", - "example": "Custom_Order_id_123", - "nullable": true, - "maxLength": 255 - }, - "order_tax_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "connector_mandate_id": { - "type": "string", - "description": "Connector Identifier for the payment method", - "nullable": true - } - } - }, - "PaymentsDynamicTaxCalculationRequest": { - "type": "object", - "required": [ - "shipping", - "client_secret", - "payment_method_type" - ], - "properties": { - "shipping": { - "$ref": "#/components/schemas/Address" - }, - "client_secret": { - "type": "string", - "description": "Client Secret" - }, - "payment_method_type": { - "$ref": "#/components/schemas/PaymentMethodType" - }, - "session_id": { - "type": "string", - "description": "Session Id", - "nullable": true - } - } - }, - "PaymentsDynamicTaxCalculationResponse": { - "type": "object", - "required": [ - "payment_id", - "net_amount", - "display_amount" - ], - "properties": { - "payment_id": { - "type": "string", - "description": "The identifier for the payment" - }, - "net_amount": { - "$ref": "#/components/schemas/MinorUnit" - }, - "order_tax_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "shipping_cost": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "display_amount": { - "$ref": "#/components/schemas/DisplayAmountOnSdk" - } - } - }, - "PaymentsExternalAuthenticationRequest": { - "type": "object", - "required": [ - "client_secret", - "device_channel", - "threeds_method_comp_ind" - ], - "properties": { - "client_secret": { - "type": "string", - "description": "Client Secret" - }, - "sdk_information": { - "allOf": [ - { - "$ref": "#/components/schemas/SdkInformation" - } - ], - "nullable": true - }, - "device_channel": { - "$ref": "#/components/schemas/DeviceChannel" - }, - "threeds_method_comp_ind": { - "$ref": "#/components/schemas/ThreeDsCompletionIndicator" - } - } - }, - "PaymentsExternalAuthenticationResponse": { - "type": "object", - "required": [ - "trans_status", - "three_ds_requestor_url" - ], - "properties": { - "trans_status": { - "$ref": "#/components/schemas/TransactionStatus" - }, - "acs_url": { - "type": "string", - "description": "Access Server URL to be used for challenge submission", - "nullable": true - }, - "challenge_request": { - "type": "string", - "description": "Challenge request which should be sent to acs_url", - "nullable": true - }, - "acs_reference_number": { - "type": "string", - "description": "Unique identifier assigned by the EMVCo(Europay, Mastercard and Visa)", - "nullable": true - }, - "acs_trans_id": { - "type": "string", - "description": "Unique identifier assigned by the ACS to identify a single transaction", - "nullable": true - }, - "three_dsserver_trans_id": { + "three_dsserver_trans_id": { "type": "string", "description": "Unique identifier assigned by the 3DS Server to identify a single transaction", "nullable": true }, "acs_signed_content": { "type": "string", - "description": "Contains the JWS object created by the ACS for the ARes(Authentication Response) message", - "nullable": true - }, - "three_ds_requestor_url": { - "type": "string", - "description": "Three DS Requestor URL" - } - } - }, - "PaymentsIncrementalAuthorizationRequest": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "integer", - "format": "int64", - "description": "The total amount including previously authorized amount and additional amount", - "example": 6540 - }, - "reason": { - "type": "string", - "description": "Reason for incremental authorization", - "nullable": true - } - } - }, - "PaymentsIntentResponse": { - "type": "object", - "required": [ - "id", - "status", - "amount_details", - "client_secret", - "profile_id", - "capture_method", - "authentication_type", - "customer_id", - "customer_present", - "setup_future_usage", - "apply_mit_exemption", - "payment_link_enabled", - "request_incremental_authorization", - "expires_on", - "request_external_three_ds_authentication" - ], - "properties": { - "id": { - "type": "string", - "description": "Global Payment Id for the payment" - }, - "status": { - "$ref": "#/components/schemas/IntentStatus" - }, - "amount_details": { - "$ref": "#/components/schemas/AmountDetailsResponse" - }, - "client_secret": { - "type": "string", - "description": "It's a token used for client side verification.", - "example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo" - }, - "profile_id": { - "type": "string", - "description": "The identifier for the profile. This is inferred from the `x-profile-id` header" - }, - "merchant_reference_id": { - "type": "string", - "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", - "example": "pay_mbabizu24mvu3mela5njyhpit4", - "nullable": true, - "maxLength": 30, - "minLength": 30 - }, - "routing_algorithm_id": { - "type": "string", - "description": "The routing algorithm id to be used for the payment", - "nullable": true - }, - "capture_method": { - "$ref": "#/components/schemas/CaptureMethod" - }, - "authentication_type": { - "allOf": [ - { - "$ref": "#/components/schemas/AuthenticationType" - } - ], - "default": "no_three_ds" - }, - "billing": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, - "shipping": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, - "customer_id": { - "type": "string", - "description": "The identifier for the customer", - "example": "12345_cus_01926c58bc6e77c09e809964e72af8c8", - "maxLength": 64, - "minLength": 32 - }, - "customer_present": { - "$ref": "#/components/schemas/PresenceOfCustomerDuringPayment" - }, - "description": { - "type": "string", - "description": "A description for the payment", - "example": "It's my first payment request", - "nullable": true - }, - "return_url": { - "type": "string", - "description": "The URL to which you want the user to be redirected after the completion of the payment operation", - "example": "https://hyperswitch.io", - "nullable": true - }, - "setup_future_usage": { - "$ref": "#/components/schemas/FutureUsage" - }, - "apply_mit_exemption": { - "$ref": "#/components/schemas/MitExemptionRequest" - }, - "statement_descriptor": { - "type": "string", - "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", - "example": "Hyperswitch Router", - "nullable": true, - "maxLength": 22 - }, - "order_details": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OrderDetailsWithAmount" - }, - "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", - "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", - "nullable": true - }, - "allowed_payment_method_types": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentMethodType" - }, - "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", - "nullable": true - }, - "metadata": { - "type": "object", - "description": "Metadata is useful for storing additional, unstructured information on an object.", - "nullable": true - }, - "connector_metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/ConnectorMetadata" - } - ], - "nullable": true - }, - "feature_metadata": { - "allOf": [ - { - "$ref": "#/components/schemas/FeatureMetadata" - } - ], - "nullable": true - }, - "payment_link_enabled": { - "$ref": "#/components/schemas/EnablePaymentLinkRequest" - }, - "payment_link_config": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentLinkConfigRequest" - } - ], - "nullable": true - }, - "request_incremental_authorization": { - "$ref": "#/components/schemas/RequestIncrementalAuthorization" - }, - "expires_on": { - "type": "string", - "format": "date-time", - "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds" - }, - "frm_metadata": { - "type": "object", - "description": "Additional data related to some frm(Fraud Risk Management) connectors", + "description": "Contains the JWS object created by the ACS for the ARes(Authentication Response) message", "nullable": true }, - "request_external_three_ds_authentication": { - "$ref": "#/components/schemas/External3dsAuthenticationRequest" + "three_ds_requestor_url": { + "type": "string", + "description": "Three DS Requestor URL" } - }, - "additionalProperties": false + } }, - "PaymentsResponse": { + "PaymentsIncrementalAuthorizationRequest": { "type": "object", "required": [ - "payment_id", - "merchant_id", - "status", - "amount", - "net_amount", - "amount_capturable", - "currency", - "payment_method", - "attempt_count" + "amount" ], "properties": { - "payment_id": { - "type": "string", - "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", - "example": "pay_mbabizu24mvu3mela5njyhpit4", - "maxLength": 30, - "minLength": 30 - }, - "merchant_id": { - "type": "string", - "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", - "example": "merchant_1668273825", - "maxLength": 255 - }, - "status": { - "allOf": [ - { - "$ref": "#/components/schemas/IntentStatus" - } - ], - "default": "requires_confirmation" - }, "amount": { "type": "integer", "format": "int64", - "description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,", - "example": 6540 - }, - "net_amount": { - "type": "integer", - "format": "int64", - "description": "The payment net amount. net_amount = amount + surcharge_details.surcharge_amount + surcharge_details.tax_amount + shipping_cost + order_tax_amount,\nIf no surcharge_details, shipping_cost, order_tax_amount, net_amount = amount", + "description": "The total amount including previously authorized amount and additional amount", "example": 6540 }, - "shipping_cost": { - "type": "integer", - "format": "int64", - "description": "The shipping cost for the payment.", - "example": 6540, - "nullable": true - }, - "amount_capturable": { - "type": "integer", - "format": "int64", - "description": "The maximum amount that could be captured from the payment", - "example": 6540, - "minimum": 100 - }, - "amount_received": { - "type": "integer", - "format": "int64", - "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540, - "nullable": true - }, - "connector": { - "type": "string", - "description": "The connector used for the payment", - "example": "stripe", - "nullable": true - }, - "client_secret": { - "type": "string", - "description": "It's a token used for client side verification.", - "example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo", - "nullable": true - }, - "created": { - "type": "string", - "format": "date-time", - "description": "Time when the payment was created", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "currency": { - "$ref": "#/components/schemas/Currency" - }, - "customer_id": { - "type": "string", - "description": "The identifier for the customer object. If not provided the customer ID will be autogenerated.\nThis field will be deprecated soon. Please refer to `customer.id`", - "deprecated": true, - "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", - "nullable": true, - "maxLength": 64, - "minLength": 1 - }, - "customer": { - "allOf": [ - { - "$ref": "#/components/schemas/CustomerDetailsResponse" - } - ], - "nullable": true - }, - "description": { - "type": "string", - "description": "A description of the payment", - "example": "It's my first payment request", - "nullable": true - }, - "refunds": { - "type": "array", - "items": { - "$ref": "#/components/schemas/RefundResponse" - }, - "description": "List of refunds that happened on this intent, as same payment intent can have multiple refund requests depending on the nature of order", - "nullable": true - }, - "disputes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DisputeResponsePaymentsRetrieve" - }, - "description": "List of disputes that happened on this intent", - "nullable": true - }, - "attempts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentAttemptResponse" - }, - "description": "List of attempts that happened on this intent", - "nullable": true - }, - "captures": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CaptureResponse" - }, - "description": "List of captures done on latest attempt", - "nullable": true - }, - "mandate_id": { - "type": "string", - "description": "A unique identifier to link the payment to a mandate, can be used instead of payment_method_data, in case of setting up recurring payments", - "example": "mandate_iwer89rnjef349dni3", - "nullable": true, - "maxLength": 255 - }, - "mandate_data": { - "allOf": [ - { - "$ref": "#/components/schemas/MandateData" - } - ], - "nullable": true - }, - "setup_future_usage": { - "allOf": [ - { - "$ref": "#/components/schemas/FutureUsage" - } - ], - "nullable": true - }, - "off_session": { - "type": "boolean", - "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with confirm=true.", - "example": true, - "nullable": true - }, - "capture_on": { - "type": "string", - "format": "date-time", - "description": "A timestamp (ISO 8601 code) that determines when the payment should be captured.\nProviding this field will automatically set `capture` to true", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "capture_method": { - "allOf": [ - { - "$ref": "#/components/schemas/CaptureMethod" - } - ], - "nullable": true - }, - "payment_method": { - "$ref": "#/components/schemas/PaymentMethod" - }, - "payment_method_data": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentMethodDataResponseWithBilling" - } - ], - "nullable": true - }, - "payment_token": { - "type": "string", - "description": "Provide a reference to a stored payment method", - "example": "187282ab-40ef-47a9-9206-5099ba31e432", - "nullable": true - }, - "shipping": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, - "billing": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, - "order_details": { - "type": "array", - "items": { - "$ref": "#/components/schemas/OrderDetailsWithAmount" - }, - "description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)", - "example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n }]", - "nullable": true - }, - "email": { - "type": "string", - "description": "description: The customer's email address\nThis field will be deprecated soon. Please refer to `customer.email` object", - "deprecated": true, - "example": "johntest@test.com", - "nullable": true, - "maxLength": 255 - }, - "name": { - "type": "string", - "description": "description: The customer's name\nThis field will be deprecated soon. Please refer to `customer.name` object", - "deprecated": true, - "example": "John Test", - "nullable": true, - "maxLength": 255 - }, - "phone": { - "type": "string", - "description": "The customer's phone number\nThis field will be deprecated soon. Please refer to `customer.phone` object", - "deprecated": true, - "example": "9123456789", - "nullable": true, - "maxLength": 255 - }, - "return_url": { + "reason": { "type": "string", - "description": "The URL to redirect after the completion of the operation", - "example": "https://hyperswitch.io", - "nullable": true - }, - "authentication_type": { - "allOf": [ - { - "$ref": "#/components/schemas/AuthenticationType" - } - ], - "default": "three_ds", + "description": "Reason for incremental authorization", "nullable": true - }, - "statement_descriptor_name": { + } + } + }, + "PaymentsIntentResponse": { + "type": "object", + "required": [ + "id", + "status", + "amount_details", + "client_secret", + "profile_id", + "capture_method", + "authentication_type", + "customer_id", + "customer_present", + "setup_future_usage", + "apply_mit_exemption", + "payment_link_enabled", + "request_incremental_authorization", + "expires_on", + "request_external_three_ds_authentication" + ], + "properties": { + "id": { "type": "string", - "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", - "example": "Hyperswitch Router", - "nullable": true, - "maxLength": 255 + "description": "Global Payment Id for the payment" }, - "statement_descriptor_suffix": { - "type": "string", - "description": "Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 255 characters for the concatenated descriptor.", - "example": "Payment for shoes purchase", - "nullable": true, - "maxLength": 255 + "status": { + "$ref": "#/components/schemas/IntentStatus" }, - "next_action": { - "allOf": [ - { - "$ref": "#/components/schemas/NextActionData" - } - ], - "nullable": true + "amount_details": { + "$ref": "#/components/schemas/AmountDetailsResponse" }, - "cancellation_reason": { + "client_secret": { "type": "string", - "description": "If the payment was cancelled the reason will be provided here", - "nullable": true + "description": "It's a token used for client side verification.", + "example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo" }, - "error_code": { + "profile_id": { "type": "string", - "description": "If there was an error while calling the connectors the code is received here", - "example": "E0001", - "nullable": true + "description": "The identifier for the profile. This is inferred from the `x-profile-id` header" }, - "error_message": { + "merchant_reference_id": { "type": "string", - "description": "If there was an error while calling the connector the error message is received here", - "example": "Failed while verifying the card", - "nullable": true + "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", + "example": "pay_mbabizu24mvu3mela5njyhpit4", + "nullable": true, + "maxLength": 30, + "minLength": 30 }, - "unified_code": { + "routing_algorithm_id": { "type": "string", - "description": "error code unified across the connectors is received here if there was an error while calling connector", + "description": "The routing algorithm id to be used for the payment", "nullable": true }, - "unified_message": { - "type": "string", - "description": "error message unified across the connectors is received here if there was an error while calling connector", - "nullable": true + "capture_method": { + "$ref": "#/components/schemas/CaptureMethod" }, - "payment_experience": { + "authentication_type": { "allOf": [ { - "$ref": "#/components/schemas/PaymentExperience" + "$ref": "#/components/schemas/AuthenticationType" } ], - "nullable": true + "default": "no_three_ds" }, - "payment_method_type": { + "billing": { "allOf": [ { - "$ref": "#/components/schemas/PaymentMethodType" + "$ref": "#/components/schemas/Address" } ], "nullable": true }, - "connector_label": { - "type": "string", - "description": "The connector used for this payment along with the country and business details", - "example": "stripe_US_food", - "nullable": true - }, - "business_country": { + "shipping": { "allOf": [ { - "$ref": "#/components/schemas/CountryAlpha2" + "$ref": "#/components/schemas/Address" } ], "nullable": true }, - "business_label": { + "customer_id": { "type": "string", - "description": "The business label of merchant for this payment", - "nullable": true + "description": "The identifier for the customer", + "example": "12345_cus_01926c58bc6e77c09e809964e72af8c8", + "maxLength": 64, + "minLength": 32 + }, + "customer_present": { + "$ref": "#/components/schemas/PresenceOfCustomerDuringPayment" }, - "business_sub_label": { + "description": { "type": "string", - "description": "The business_sub_label for this payment", + "description": "A description for the payment", + "example": "It's my first payment request", "nullable": true }, - "allowed_payment_method_types": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentMethodType" - }, - "description": "Allowed Payment Method Types for a given PaymentIntent", + "return_url": { + "type": "string", + "description": "The URL to which you want the user to be redirected after the completion of the payment operation", + "example": "https://hyperswitch.io", "nullable": true }, - "ephemeral_key": { - "allOf": [ - { - "$ref": "#/components/schemas/EphemeralKeyCreateResponse" - } - ], - "nullable": true + "setup_future_usage": { + "$ref": "#/components/schemas/FutureUsage" }, - "manual_retry_allowed": { - "type": "boolean", - "description": "If true the payment can be retried with same or different payment method which means the confirm call can be made again.", - "nullable": true + "apply_mit_exemption": { + "$ref": "#/components/schemas/MitExemptionRequest" }, - "connector_transaction_id": { + "statement_descriptor": { "type": "string", - "description": "A unique identifier for a payment provided by the connector", - "example": "993672945374576J", + "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", + "example": "Hyperswitch Router", + "nullable": true, + "maxLength": 22 + }, + "order_details": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OrderDetailsWithAmount" + }, + "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", + "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", "nullable": true }, - "frm_message": { - "allOf": [ - { - "$ref": "#/components/schemas/FrmMessage" - } - ], + "allowed_payment_method_types": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodType" + }, + "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", "nullable": true }, "metadata": { "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "description": "Metadata is useful for storing additional, unstructured information on an object.", "nullable": true }, "connector_metadata": { @@ -16096,154 +15095,35 @@ ], "nullable": true }, - "reference_id": { - "type": "string", - "description": "reference(Identifier) to the payment at connector side", - "example": "993672945374576J", - "nullable": true - }, - "payment_link": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentLinkResponse" - } - ], - "nullable": true - }, - "profile_id": { - "type": "string", - "description": "The business profile that is associated with this payment", - "nullable": true - }, - "surcharge_details": { - "allOf": [ - { - "$ref": "#/components/schemas/RequestSurchargeDetails" - } - ], - "nullable": true - }, - "attempt_count": { - "type": "integer", - "format": "int32", - "description": "Total number of attempts associated with this payment" - }, - "merchant_decision": { - "type": "string", - "description": "Denotes the action(approve or reject) taken by merchant in case of manual review. Manual review can occur when the transaction is marked as risky by the frm_processor, payment processor or when there is underpayment/over payment incase of crypto payment", - "nullable": true - }, - "merchant_connector_id": { - "type": "string", - "description": "Identifier of the connector ( merchant connector account ) which was chosen to make the payment", - "nullable": true - }, - "incremental_authorization_allowed": { - "type": "boolean", - "description": "If true, incremental authorization can be performed on this payment, in case the funds authorized initially fall short.", - "nullable": true - }, - "authorization_count": { - "type": "integer", - "format": "int32", - "description": "Total number of authorizations happened in an incremental_authorization payment", - "nullable": true - }, - "incremental_authorizations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncrementalAuthorizationResponse" - }, - "description": "List of incremental authorizations happened to the payment", - "nullable": true + "payment_link_enabled": { + "$ref": "#/components/schemas/EnablePaymentLinkRequest" }, - "external_authentication_details": { + "payment_link_config": { "allOf": [ { - "$ref": "#/components/schemas/ExternalAuthenticationDetailsResponse" + "$ref": "#/components/schemas/PaymentLinkConfigRequest" } ], "nullable": true }, - "external_3ds_authentication_attempted": { - "type": "boolean", - "description": "Flag indicating if external 3ds authentication is made or not", - "nullable": true + "request_incremental_authorization": { + "$ref": "#/components/schemas/RequestIncrementalAuthorization" }, "expires_on": { "type": "string", "format": "date-time", - "description": "Date Time for expiry of the payment", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "fingerprint": { - "type": "string", - "description": "Payment Fingerprint, to identify a particular card.\nIt is a 20 character long alphanumeric code.", - "nullable": true - }, - "browser_info": { - "allOf": [ - { - "$ref": "#/components/schemas/BrowserInformation" - } - ], - "nullable": true - }, - "payment_method_id": { - "type": "string", - "description": "Identifier for Payment Method used for the payment", - "nullable": true - }, - "payment_method_status": { - "allOf": [ - { - "$ref": "#/components/schemas/PaymentMethodStatus" - } - ], - "nullable": true - }, - "updated": { - "type": "string", - "format": "date-time", - "description": "Date time at which payment was updated", - "example": "2022-09-10T10:11:12Z", - "nullable": true - }, - "split_payments": { - "allOf": [ - { - "$ref": "#/components/schemas/SplitPaymentsResponse" - } - ], - "nullable": true + "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds" }, "frm_metadata": { "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. FRM Metadata is useful for storing additional, structured information on an object related to FRM.", - "nullable": true - }, - "merchant_order_reference_id": { - "type": "string", - "description": "Merchant's identifier for the payment/invoice. This will be sent to the connector\nif the connector provides support to accept multiple reference ids.\nIn case the connector supports only one reference id, Hyperswitch's Payment ID will be sent as reference.", - "example": "Custom_Order_id_123", - "nullable": true, - "maxLength": 255 - }, - "order_tax_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], + "description": "Additional data related to some frm(Fraud Risk Management) connectors", "nullable": true }, - "connector_mandate_id": { - "type": "string", - "description": "Connector Identifier for the payment method", - "nullable": true + "request_external_three_ds_authentication": { + "$ref": "#/components/schemas/External3dsAuthenticationRequest" } - } + }, + "additionalProperties": false }, "PaymentsRetrieveRequest": { "type": "object", @@ -19046,6 +17926,21 @@ } } }, + "ResourceId": { + "oneOf": [ + { + "type": "object", + "required": [ + "customer" + ], + "properties": { + "customer": { + "type": "string" + } + } + } + ] + }, "ResponsePaymentMethodTypes": { "allOf": [ { diff --git a/crates/api_models/src/ephemeral_key.rs b/crates/api_models/src/ephemeral_key.rs index fa61642e353a..7cdea0028912 100644 --- a/crates/api_models/src/ephemeral_key.rs +++ b/crates/api_models/src/ephemeral_key.rs @@ -18,18 +18,30 @@ pub struct EphemeralKeyCreateRequest { pub customer_id: id_type::CustomerId, } +#[cfg(feature = "v2")] +#[derive( + Clone, + // Copy, + Debug, + serde::Serialize, + serde::Deserialize, + // strum::EnumString, + PartialEq, + Eq, + ToSchema, +)] +#[serde(rename_all = "snake_case")] +pub enum ResourceId { + #[schema(value_type = String)] + Customer(id_type::GlobalCustomerId), +} + #[cfg(feature = "v2")] /// Information required to create an ephemeral key. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] pub struct EphemeralKeyCreateRequest { - /// Customer ID for which an ephemeral key must be created - #[schema( - min_length = 32, - max_length = 64, - value_type = String, - example = "12345_cus_01926c58bc6e77c09e809964e72af8c8" - )] - pub customer_id: id_type::GlobalCustomerId, + /// Resource ID for which an ephemeral key must be created + pub resource_id: ResourceId, } #[cfg(feature = "v2")] @@ -40,8 +52,8 @@ pub struct EphemeralKeyResponse { #[schema(value_type = String, max_length = 32, min_length = 1)] pub id: id_type::EphemeralKeyId, /// customer_id to which this ephemeral key belongs to - #[schema(value_type = String, max_length = 64, min_length = 32, example = "12345_cus_01926c58bc6e77c09e809964e72af8c8")] - pub customer_id: id_type::GlobalCustomerId, + #[schema(value_type = ResourceId)] + pub resource_id: ResourceId, /// time at which this ephemeral key was created pub created_at: time::PrimitiveDateTime, /// time at which this ephemeral key would expire @@ -64,6 +76,7 @@ impl common_utils::events::ApiEventMetric for EphemeralKeyResponse { } } +#[cfg(feature = "v1")] /// ephemeral_key for the customer_id mentioned #[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Eq, PartialEq, ToSchema)] pub struct EphemeralKeyCreateResponse { diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs index e6de6190b83d..7c7ba0605410 100644 --- a/crates/api_models/src/events/payment.rs +++ b/crates/api_models/src/events/payment.rs @@ -10,6 +10,8 @@ use super::{ not(feature = "payment_methods_v2") ))] use crate::payment_methods::CustomerPaymentMethodsListResponse; +#[cfg(feature = "v1")] +use crate::payments::{PaymentListResponse, PaymentListResponseV2, PaymentsResponse}; #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] use crate::{events, payment_methods::CustomerPaymentMethodsListResponse}; use crate::{ @@ -23,15 +25,14 @@ use crate::{ payments::{ self, ExtendedCardInfoResponse, PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters, PaymentListFiltersV2, - PaymentListResponse, PaymentListResponseV2, PaymentsAggregateResponse, - PaymentsApproveRequest, PaymentsCancelRequest, PaymentsCaptureRequest, - PaymentsCompleteAuthorizeRequest, PaymentsDynamicTaxCalculationRequest, - PaymentsDynamicTaxCalculationResponse, PaymentsExternalAuthenticationRequest, - PaymentsExternalAuthenticationResponse, PaymentsIncrementalAuthorizationRequest, - PaymentsManualUpdateRequest, PaymentsManualUpdateResponse, - PaymentsPostSessionTokensRequest, PaymentsPostSessionTokensResponse, PaymentsRejectRequest, - PaymentsResponse, PaymentsRetrieveRequest, PaymentsSessionResponse, PaymentsStartRequest, - RedirectionResponse, + PaymentsAggregateResponse, PaymentsApproveRequest, PaymentsCancelRequest, + PaymentsCaptureRequest, PaymentsCompleteAuthorizeRequest, + PaymentsDynamicTaxCalculationRequest, PaymentsDynamicTaxCalculationResponse, + PaymentsExternalAuthenticationRequest, PaymentsExternalAuthenticationResponse, + PaymentsIncrementalAuthorizationRequest, PaymentsManualUpdateRequest, + PaymentsManualUpdateResponse, PaymentsPostSessionTokensRequest, + PaymentsPostSessionTokensResponse, PaymentsRejectRequest, PaymentsRetrieveRequest, + PaymentsSessionResponse, PaymentsStartRequest, RedirectionResponse, }, }; @@ -355,12 +356,14 @@ impl ApiEventMetric for PaymentListConstraints { } } +#[cfg(feature = "v1")] impl ApiEventMetric for PaymentListResponse { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::ResourceListAPI) } } +#[cfg(feature = "v1")] impl ApiEventMetric for PaymentListResponseV2 { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::ResourceListAPI) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b6152cc97874..6177f9070bb5 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -27,12 +27,13 @@ use time::{Date, PrimitiveDateTime}; use url::Url; use utoipa::ToSchema; +#[cfg(feature = "v1")] +use crate::ephemeral_key::EphemeralKeyCreateResponse; #[cfg(feature = "v2")] use crate::payment_methods; use crate::{ admin::{self, MerchantConnectorInfo}, disputes, enums as api_enums, - ephemeral_key::EphemeralKeyCreateResponse, mandates::RecurringDetails, refunds, }; @@ -4411,6 +4412,7 @@ pub struct ReceiverDetails { amount_remaining: Option, } +#[cfg(feature = "v1")] #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema, router_derive::PolymorphicSchema)] #[generate_schemas(PaymentsCreateResponseOpenApi)] pub struct PaymentsResponse { @@ -5101,6 +5103,7 @@ pub struct PaymentListConstraints { pub created_gte: Option, } +#[cfg(feature = "v1")] #[derive(Clone, Debug, serde::Serialize, ToSchema)] pub struct PaymentListResponse { /// The number of payments included in the list @@ -5127,6 +5130,7 @@ pub struct IncrementalAuthorizationResponse { pub previously_authorized_amount: MinorUnit, } +#[cfg(feature = "v1")] #[derive(Clone, Debug, serde::Serialize)] pub struct PaymentListResponseV2 { /// The number of payments included in the list for given constraints diff --git a/crates/api_models/src/webhooks.rs b/crates/api_models/src/webhooks.rs index f99e3a450b20..ddefea542c2d 100644 --- a/crates/api_models/src/webhooks.rs +++ b/crates/api_models/src/webhooks.rs @@ -285,7 +285,7 @@ pub enum OutgoingWebhookContent { #[serde(tag = "type", content = "object", rename_all = "snake_case")] #[cfg(feature = "v2")] pub enum OutgoingWebhookContent { - #[schema(value_type = PaymentsResponse, title = "PaymentsResponse")] + #[schema(value_type = PaymentsRetrieveResponse, title = "PaymentsResponse")] PaymentDetails(Box), #[schema(value_type = RefundResponse, title = "RefundResponse")] RefundDetails(Box), diff --git a/crates/diesel_models/src/ephemeral_key.rs b/crates/diesel_models/src/ephemeral_key.rs index c7fc103ed09b..7800b489c567 100644 --- a/crates/diesel_models/src/ephemeral_key.rs +++ b/crates/diesel_models/src/ephemeral_key.rs @@ -4,9 +4,8 @@ use masking::{PeekInterface, Secret}; pub struct EphemeralKeyTypeNew { pub id: common_utils::id_type::EphemeralKeyId, pub merchant_id: common_utils::id_type::MerchantId, - pub customer_id: common_utils::id_type::GlobalCustomerId, pub secret: Secret, - pub resource_type: ResourceType, + pub resource_id: ResourceId, } #[cfg(feature = "v2")] @@ -14,8 +13,7 @@ pub struct EphemeralKeyTypeNew { pub struct EphemeralKeyType { pub id: common_utils::id_type::EphemeralKeyId, pub merchant_id: common_utils::id_type::MerchantId, - pub customer_id: common_utils::id_type::GlobalCustomerId, - pub resource_type: ResourceType, + pub resource_id: ResourceId, pub created_at: time::PrimitiveDateTime, pub expires: time::PrimitiveDateTime, pub secret: Secret, @@ -51,20 +49,11 @@ impl common_utils::events::ApiEventMetric for EphemeralKey { } } -#[derive( - Clone, - Copy, - Debug, - serde::Serialize, - serde::Deserialize, - strum::Display, - strum::EnumString, - PartialEq, - Eq, -)] +#[cfg(feature = "v2")] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] -#[strum(serialize_all = "snake_case")] -pub enum ResourceType { - Payment, - PaymentMethod, +pub enum ResourceId { + Payment(common_utils::id_type::GlobalPaymentId), + PaymentMethod(common_utils::id_type::GlobalPaymentMethodId), + Customer(common_utils::id_type::GlobalCustomerId), } diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 5b4c89c3f4a6..001d15a02919 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -188,6 +188,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::customers::CustomerRequest, api_models::customers::CustomerUpdateRequest, api_models::customers::CustomerDeleteResponse, + api_models::ephemeral_key::ResourceId, api_models::payment_methods::PaymentMethodCreate, api_models::payment_methods::PaymentMethodIntentCreate, api_models::payment_methods::PaymentMethodIntentConfirm, @@ -358,8 +359,6 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::CardRedirectData, api_models::payments::CardToken, api_models::payments::CustomerAcceptance, - api_models::payments::PaymentsResponse, - api_models::payments::PaymentsCreateResponseOpenApi, api_models::payments::PaymentRetrieveBody, api_models::payments::PaymentsRetrieveRequest, api_models::payments::PaymentsCaptureRequest, @@ -423,7 +422,6 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::SamsungPayTokenData, api_models::payments::PaymentsCancelRequest, api_models::payments::PaymentListConstraints, - api_models::payments::PaymentListResponse, api_models::payments::CashappQr, api_models::payments::BankTransferData, api_models::payments::BankTransferNextStepsData, @@ -493,7 +491,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::mandates::MandateCardDetails, api_models::mandates::RecurringDetails, api_models::mandates::ProcessorPaymentToken, - api_models::ephemeral_key::EphemeralKeyCreateResponse, + api_models::ephemeral_key::EphemeralKeyResponse, api_models::payments::CustomerDetails, api_models::payments::GiftCardData, api_models::payments::GiftCardDetails, diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs index 25ece15d47d5..0f48ce1cd1bf 100644 --- a/crates/router/src/core/payment_methods.rs +++ b/crates/router/src/core/payment_methods.rs @@ -1403,9 +1403,8 @@ pub async fn create_payment_method_for_intent( let db = &*state.store; let ephemeral_key = payment_helpers::create_ephemeral_key( state, - customer_id, merchant_id, - ephemeral_key::ResourceType::PaymentMethod, + diesel_models::ResourceId::PaymentMethod(payment_method_id.clone()), ) .await .change_context(errors::ApiErrorResponse::InternalServerError) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 0b44278359b2..68d5b61e50e9 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3054,67 +3054,74 @@ pub async fn make_ephemeral_key( #[cfg(feature = "v2")] pub async fn make_ephemeral_key( state: SessionState, - customer_id: id_type::GlobalCustomerId, + resource_id: api_models::ephemeral_key::ResourceId, merchant_account: domain::MerchantAccount, key_store: domain::MerchantKeyStore, headers: &actix_web::http::header::HeaderMap, ) -> errors::RouterResponse { let db = &state.store; let key_manager_state = &((&state).into()); - db.find_customer_by_global_id( - key_manager_state, - &customer_id, - merchant_account.get_id(), - &key_store, - merchant_account.storage_scheme, - ) - .await - .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?; - - let resource_type = services::authentication::get_header_value_by_key( - headers::X_RESOURCE_TYPE.to_string(), - headers, - )? - .map(ephemeral_key::ResourceType::from_str) - .transpose() - .change_context(errors::ApiErrorResponse::InvalidRequestData { - message: format!("`{}` header is invalid", headers::X_RESOURCE_TYPE), - })? - .get_required_value("ResourceType") - .attach_printable("Failed to convert ResourceType from string")?; - - let ephemeral_key = create_ephemeral_key( - &state, - &customer_id, - merchant_account.get_id(), - resource_type, - ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Unable to create ephemeral key")?; - let response = EphemeralKeyResponse::foreign_from(ephemeral_key); + match &resource_id { + api_models::ephemeral_key::ResourceId::Customer(global_customer_id) => { + db.find_customer_by_global_id( + key_manager_state, + global_customer_id, + merchant_account.get_id(), + &key_store, + merchant_account.storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?; + } + } + + // TODO: Supersede in V2Auth + // services::authentication::get_header_value_by_key( + // headers::X_RESOURCE_TYPE.to_string(), + // headers, + // )? + // .map(diesel_models::ResourceId::validate_enum_str) + // .transpose() + // .change_context(errors::ApiErrorResponse::InvalidRequestData { + // message: format!("`{}` header is invalid", headers::X_RESOURCE_TYPE), + // })? + // .get_required_value("ResourceType") + // .attach_printable("Failed to convert ResourceType from string")?; + + let resource_id = match resource_id { + api_models::ephemeral_key::ResourceId::Customer(global_customer_id) => { + diesel_models::ResourceId::Customer(global_customer_id) + } + }; + + let ephemeral_key = create_ephemeral_key(&state, merchant_account.get_id(), resource_id) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to create ephemeral key")?; + + let response = EphemeralKeyResponse::foreign_try_from(ephemeral_key) + .attach_printable("Only customer is supported as resource_id in response")?; Ok(services::ApplicationResponse::Json(response)) } #[cfg(feature = "v2")] pub async fn create_ephemeral_key( state: &SessionState, - customer_id: &id_type::GlobalCustomerId, merchant_id: &id_type::MerchantId, - resource_type: ephemeral_key::ResourceType, + resource_id: diesel_models::ephemeral_key::ResourceId, ) -> RouterResult { use common_utils::generate_time_ordered_id; let store = &state.store; let id = id_type::EphemeralKeyId::generate(); let secret = masking::Secret::new(generate_time_ordered_id("epk")); + let ephemeral_key = ephemeral_key::EphemeralKeyTypeNew { id, - customer_id: customer_id.to_owned(), merchant_id: merchant_id.to_owned(), secret, - resource_type, + resource_id, }; let ephemeral_key = store .create_ephemeral_key(ephemeral_key, state.conf.eph_key.validity) @@ -3157,10 +3164,12 @@ pub async fn delete_ephemeral_key( }) .attach_printable("Unable to delete ephemeral key")?; - let response = EphemeralKeyResponse::foreign_from(ephemeral_key); + let response = EphemeralKeyResponse::foreign_try_from(ephemeral_key) + .attach_printable("Only customer is supported as resource_id in response")?; Ok(services::ApplicationResponse::Json(response)) } +#[cfg(feature = "v1")] pub fn make_pg_redirect_response( payment_id: id_type::PaymentId, response: &api::PaymentsResponse, diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 70db7a581a20..175fc21f62e6 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -1714,7 +1714,7 @@ pub fn payments_to_payments_response( _connector_http_status_code: Option, _external_latency: Option, _is_latency_header_enabled: Option, -) -> RouterResponse +) -> RouterResponse where Op: Debug, D: OperationSessionGetters, @@ -2554,6 +2554,7 @@ impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::Pay } } +#[cfg(feature = "v1")] impl ForeignFrom for api::ephemeral_key::EphemeralKeyCreateResponse { fn foreign_from(from: ephemeral_key::EphemeralKey) -> Self { Self { diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 5e126310fa6c..585a093ce12e 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -1415,6 +1415,7 @@ pub fn get_external_authentication_request_poll_id( payment_id.get_external_authentication_request_poll_id() } +#[cfg(feature = "v1")] pub fn get_html_redirect_response_for_external_authentication( return_url_with_query_params: String, payment_response: &api_models::payments::PaymentsResponse, diff --git a/crates/router/src/db/ephemeral_key.rs b/crates/router/src/db/ephemeral_key.rs index a77995e4e58e..5eaa799920c8 100644 --- a/crates/router/src/db/ephemeral_key.rs +++ b/crates/router/src/db/ephemeral_key.rs @@ -3,7 +3,7 @@ use common_utils::id_type; use time::ext::NumericalDuration; #[cfg(feature = "v2")] -use crate::types::storage::ephemeral_key::{EphemeralKeyType, EphemeralKeyTypeNew, ResourceType}; +use crate::types::storage::ephemeral_key::{EphemeralKeyType, EphemeralKeyTypeNew}; use crate::{ core::errors::{self, CustomResult}, db::MockDb, @@ -67,9 +67,7 @@ mod storage { use super::EphemeralKeyInterface; #[cfg(feature = "v2")] - use crate::types::storage::ephemeral_key::{ - EphemeralKeyType, EphemeralKeyTypeNew, ResourceType, - }; + use crate::types::storage::ephemeral_key::{EphemeralKeyType, EphemeralKeyTypeNew}; use crate::{ core::errors::{self, CustomResult}, services::Store, @@ -149,10 +147,9 @@ mod storage { id: new.id, created_at, expires, - customer_id: new.customer_id, merchant_id: new.merchant_id, secret: new.secret, - resource_type: new.resource_type, + resource_id: new.resource_id, }; let secret_key = created_ephemeral_key.generate_secret_key(); diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index 8c2bca5a82e6..f3b15c8c2ebd 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -91,7 +91,6 @@ pub mod headers { pub const X_TENANT_ID: &str = "x-tenant-id"; pub const X_CLIENT_SECRET: &str = "X-Client-Secret"; pub const X_CONNECTED_MERCHANT_ID: &str = "x-connected-merchant-id"; - pub const X_RESOURCE_TYPE: &str = "X-Resource-Type"; } pub mod pii { diff --git a/crates/router/src/routes/ephemeral_key.rs b/crates/router/src/routes/ephemeral_key.rs index 0330482e81a9..479bdb4e8aba 100644 --- a/crates/router/src/routes/ephemeral_key.rs +++ b/crates/router/src/routes/ephemeral_key.rs @@ -51,7 +51,7 @@ pub async fn ephemeral_key_create( |state, auth: auth::AuthenticationData, payload, _| { helpers::make_ephemeral_key( state, - payload.customer_id.to_owned(), + payload.resource_id.to_owned(), auth.merchant_account, auth.key_store, req.headers(), diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs index c8e6303562c9..1aaff740ae9c 100644 --- a/crates/router/src/routes/payment_methods.rs +++ b/crates/router/src/routes/payment_methods.rs @@ -222,16 +222,11 @@ pub async fn list_payment_methods_enabled( let flow = Flow::PaymentMethodsList; let payment_method_id = path.into_inner(); - let auth = match auth::is_ephemeral_or_publishible_auth(req.headers()) { - Ok(auth) => auth, - Err(e) => return api::log_and_return_error_response(e), - }; - Box::pin(api::server_wrap( flow, state, &req, - payment_method_id, + payment_method_id.clone(), |state, auth: auth::AuthenticationData, payment_method_id, _| { payment_methods_routes::list_payment_methods_enabled( state, @@ -241,7 +236,7 @@ pub async fn list_payment_methods_enabled( payment_method_id, ) }, - &*auth, + &auth::V2Auth::ClientAuth(diesel_models::ResourceId::PaymentMethod(payment_method_id)), api_locking::LockAction::NotApplicable, )) .await diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index 99800b555123..5341ea05d24a 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -20,6 +20,8 @@ use common_utils::{date_time, id_type}; use diesel_models::ephemeral_key; use error_stack::{report, ResultExt}; use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; +#[cfg(feature = "v2")] +use masking::ExposeInterface; use masking::PeekInterface; use router_env::logger; use serde::Serialize; @@ -1529,19 +1531,20 @@ where .await .change_context(errors::ApiErrorResponse::Unauthorized)?; - let resource_type = HeaderMapStruct::new(request_headers) - .get_mandatory_header_value_by_key(headers::X_RESOURCE_TYPE) - .and_then(|val| { - ephemeral_key::ResourceType::from_str(val).change_context( - errors::ApiErrorResponse::InvalidRequestData { - message: format!("`{}` header is invalid", headers::X_RESOURCE_TYPE), - }, - ) - })?; - - fp_utils::when(resource_type != ephemeral_key.resource_type, || { - Err(errors::ApiErrorResponse::Unauthorized) - })?; + // TODO: Supersede in V2Auth + // let resource_type = HeaderMapStruct::new(request_headers) + // .get_mandatory_header_value_by_key(headers::X_RESOURCE_TYPE) + // .and_then(|val| { + // ephemeral_key::ResourceId::validate_enum_str(val).change_context( + // errors::ApiErrorResponse::InvalidRequestData { + // message: format!("`{}` header is invalid", headers::X_RESOURCE_TYPE), + // }, + // ) + // })?; + + // fp_utils::when(resource_type != ephemeral_key.resource_id, || { + // Err(errors::ApiErrorResponse::Unauthorized) + // })?; MerchantIdAuth(ephemeral_key.merchant_id) .authenticate_and_fetch(request_headers, state) @@ -1778,6 +1781,109 @@ where } } +#[derive(Debug)] +#[cfg(feature = "v2")] +pub enum V2Auth { + ApiKeyAuth, // API Key + ClientAuth(ephemeral_key::ResourceId), // Publishable Key + Ephemeral Key + DashboardAuth, // JWT +} + +#[cfg(feature = "v2")] +#[async_trait] +impl AuthenticateAndFetch for V2Auth +where + A: SessionStateInfo + Sync, +{ + async fn authenticate_and_fetch( + &self, + request_headers: &HeaderMap, + state: &A, + ) -> RouterResult<(AuthenticationData, AuthenticationType)> { + let auth_string = request_headers + .get(headers::AUTHORIZATION) + .get_required_value(headers::AUTHORIZATION)? + .to_str() + .change_context(errors::ApiErrorResponse::InvalidDataValue { + field_name: headers::AUTHORIZATION, + }) + .attach_printable("Failed to convert authorization header to string")? + .to_owned(); + + match self { + Self::ApiKeyAuth => Err(errors::ApiErrorResponse::Unauthorized.into()), + Self::ClientAuth(resource_id) => { + let publishable_key = auth_string + .split(',') + .find_map(|part| part.trim().strip_prefix("publishable-key=")) + .ok_or_else(|| { + report!(errors::ApiErrorResponse::Unauthorized) + .attach_printable("Unable to parse publishable_key") + })?; + + let ephemeral_key = auth_string + .split(',') + .find_map(|part| part.trim().strip_prefix("ephemeral-key=")) + .ok_or_else(|| { + report!(errors::ApiErrorResponse::Unauthorized) + .attach_printable("Unable to parse ephemeral_key") + })?; + + let key_manager_state = &(&state.session_state()).into(); + + let db_ephemeral_key = state + .store() + .get_ephemeral_key(ephemeral_key) + .await + .change_context(errors::ApiErrorResponse::Unauthorized) + .attach_printable("Invalid ephemeral_key")?; + + if db_ephemeral_key.secret.expose() == ephemeral_key + && resource_id == &db_ephemeral_key.resource_id + { + let profile_id = get_id_type_by_key_from_headers( + headers::X_PROFILE_ID.to_string(), + request_headers, + )? + .get_required_value(headers::X_PROFILE_ID)?; + + let (merchant_account, key_store) = state + .store() + .find_merchant_account_by_publishable_key( + key_manager_state, + publishable_key, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?; + let merchant_id = merchant_account.get_id().clone(); + let profile = state + .store() + .find_business_profile_by_merchant_id_profile_id( + key_manager_state, + &key_store, + &merchant_id, + &profile_id, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::Unauthorized)?; + Ok(( + AuthenticationData { + merchant_account, + key_store, + profile, + platform_merchant_account: None, + }, + AuthenticationType::PublishableKey { merchant_id }, + )) + } else { + Err(errors::ApiErrorResponse::Unauthorized.into()) + } + } + Self::DashboardAuth => Err(errors::ApiErrorResponse::Unauthorized.into()), + } + } +} + #[derive(Debug)] pub struct PublishableKeyAuth; diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 2ae2af924785..1d0cdaad3df0 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -542,6 +542,7 @@ pub struct RedirectPaymentFlowResponse { pub profile: domain::Profile, } +#[cfg(feature = "v1")] #[derive(Clone, Debug)] pub struct AuthenticatePaymentFlowResponse { pub payments_response: api_models::payments::PaymentsResponse, diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 6ec0fe701e9c..2c5b07359c8a 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -1,5 +1,7 @@ #[cfg(feature = "v1")] pub use api_models::payments::PaymentsRequest; +#[cfg(feature = "v1")] +pub use api_models::payments::{PaymentListResponse, PaymentListResponseV2, PaymentsResponse}; #[cfg(feature = "v2")] pub use api_models::payments::{ PaymentsCreateIntentRequest, PaymentsIntentResponse, PaymentsUpdateIntentRequest, @@ -14,15 +16,15 @@ pub use api_models::{ MandateTransactionType, MandateType, MandateValidationFields, NextActionType, OnlineMandate, OpenBankingSessionToken, PayLaterData, PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters, - PaymentListFiltersV2, PaymentListResponse, PaymentListResponseV2, PaymentMethodData, - PaymentMethodDataRequest, PaymentMethodDataResponse, PaymentOp, PaymentRetrieveBody, + PaymentListFiltersV2, PaymentMethodData, PaymentMethodDataRequest, + PaymentMethodDataResponse, PaymentOp, PaymentRetrieveBody, PaymentRetrieveBodyWithCredentials, PaymentsAggregateResponse, PaymentsApproveRequest, PaymentsCancelRequest, PaymentsCaptureRequest, PaymentsCompleteAuthorizeRequest, PaymentsDynamicTaxCalculationRequest, PaymentsDynamicTaxCalculationResponse, PaymentsExternalAuthenticationRequest, PaymentsIncrementalAuthorizationRequest, PaymentsManualUpdateRequest, PaymentsPostSessionTokensRequest, PaymentsPostSessionTokensResponse, PaymentsRedirectRequest, PaymentsRedirectionResponse, - PaymentsRejectRequest, PaymentsResponse, PaymentsResponseForm, PaymentsRetrieveRequest, + PaymentsRejectRequest, PaymentsResponseForm, PaymentsRetrieveRequest, PaymentsSessionRequest, PaymentsSessionResponse, PaymentsStartRequest, PgRedirectResponse, PhoneDetails, RedirectionResponse, SessionToken, UrlDetails, VerifyRequest, VerifyResponse, WalletData, diff --git a/crates/router/src/types/storage/ephemeral_key.rs b/crates/router/src/types/storage/ephemeral_key.rs index c4b8e2ba701a..bc8257e58d2f 100644 --- a/crates/router/src/types/storage/ephemeral_key.rs +++ b/crates/router/src/types/storage/ephemeral_key.rs @@ -1,18 +1,29 @@ +use api_models::errors::types::ApiError; pub use diesel_models::ephemeral_key::{EphemeralKey, EphemeralKeyNew}; #[cfg(feature = "v2")] -pub use diesel_models::ephemeral_key::{EphemeralKeyType, EphemeralKeyTypeNew, ResourceType}; +pub use diesel_models::ephemeral_key::{EphemeralKeyType, EphemeralKeyTypeNew}; +use crate::db::errors; #[cfg(feature = "v2")] -use crate::types::transformers::ForeignFrom; +use crate::types::transformers::ForeignTryFrom; #[cfg(feature = "v2")] -impl ForeignFrom for api_models::ephemeral_key::EphemeralKeyResponse { - fn foreign_from(from: EphemeralKeyType) -> Self { - Self { - customer_id: from.customer_id, - created_at: from.created_at, - expires: from.expires, - secret: from.secret, - id: from.id, +impl ForeignTryFrom for api_models::ephemeral_key::EphemeralKeyResponse { + type Error = errors::ApiErrorResponse; + fn foreign_try_from(from: EphemeralKeyType) -> Result { + match from.resource_id { + diesel_models::ResourceId::Payment(global_payment_id) => { + Err(errors::ApiErrorResponse::InternalServerError) + } + diesel_models::ResourceId::PaymentMethod(global_payment_method_id) => { + Err(errors::ApiErrorResponse::InternalServerError) + } + diesel_models::ResourceId::Customer(global_customer_id) => Ok(Self { + resource_id: api_models::ephemeral_key::ResourceId::Customer(global_customer_id), + created_at: from.created_at, + expires: from.expires, + secret: from.secret, + id: from.id, + }), } } }