# Server-To-Server Payments ## Overview **Server-To-Server** payments allow merchants who are PCI SAQ-D compliant to collect customer card details directly on their own platform and then pass them to Ryft to handle any required authentication (e.g., 3D-Secure) and process the payment. Please note that, we require the PCI certification before we can enable Server-To-Server payments on your account. For more information, please contact your Account Manager. ## Requirements To process Server-To-Server payments, you must ensure that the following requirements are met: 1. Initiate a payment by creating a Payment Session according to the payment type you want to process (e.g., Standard, Recurring, Unscheduled, etc.) as described in the relevant [Initiate Payments](/documentation/get_started/initiate_payments) page. The response payload will include a `clientSecret` that you will need to use later. 2. Collect the customer's card details directly on your platform using your own secure form. This process avoids the need to use the Ryft embedded SDK on your website to collect the card details. Once you have satisfied all the requirements described in the previous section, you can proceed to process the Server-To-Server payment. ## Processing Server-To-Server Payments To process a Server-To-Server payment, you will need to use the [paymentSessionAttemptPayment](/documentation/api/reference/openapi#operation/paymentSessionAttemptPayment) endpoint. Whether your integration is via a mobile app or a web application, you must supply the `threeDsRequestDetails` object in the request body when calling the `paymentSessionAttemptPayment` endpoint. This object contains information about the customer's environment and the context of the transaction, which is essential for performing 3D-Secure authentication. Below is an example of how to call the `paymentSessionAttemptPayment` endpoint with all the required parameters to process a Server-To-Server payment: Web Application ```json paymentSessionAttemptPayment - Web Application - Payload Example { "clientSecret": "ps_XXXXXXXXXXXXXXXXXXXX", // Replace with your actual client secret returned from the Payment Session creation API call "cardDetails": { "number": "XXXXXXXXXXXXXXXXXX", // Replace with the actual card number "expiryMonth": "mm", // Replace with the actual expiry month "expiryYear": "yyyy", // Replace with the actual expiry year "cvc": "xxx", // Replace with the actual CVC }, "threeDsRequestDetails": { "deviceChannel": "Browser", "browserDetails": { "acceptHeader": "application/json,text/plain,text/html,*/*", "colorDepth": 24, "javaEnabled": true, "language": "en-GB", "screenHeight": 900, "screenWidth": 1440, "timeZoneOffset": -120, "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" } } } ``` The `threeDsRequestDetails.browserDetails` object must be populated with the actual details of the customer's browser environment. You can collect this information using JavaScript on your web application as follows: - `acceptHeader`: retrieve the value used on HTTP requests prior to the payment submission. - `colorDepth`: use the `window.navigator.colorDepth` property. - `javaEnabled`: use the `window.navigator.javaEnabled()` method. - `language`: use the `window.navigator.language` property. - `screenHeight`: use the `window.screen.height` property. - `screenWidth`: use the `window.screen.width` property. - `timeZoneOffset`: use the `getTimezoneOffset()` method of the JavaScript `Date` object (e.g., `new Date().getTimezoneOffset()`). - `userAgent`: use the `window.navigator.userAgent` property. Mobile Application ```json paymentSessionAttemptPayment - Mobile Application - Payload Example { "clientSecret": "ps_XXXXXXXXXXXXXXXXXXXX", // Replace with your actual client secret returned from the Payment Session creation API call "cardDetails": { "number": "XXXXXXXXXXXXXXXXXX", // Replace with the actual card number "expiryMonth": "mm", // Replace with the actual expiry month "expiryYear": "yyyy", // Replace with the actual expiry year "cvc": "xxx", // Replace with the actual CVC }, "threeDsRequestDetails": { "deviceChannel": "Application" } } ``` In a mobile application, the `threeDsRequestDetails` object only requires the `deviceChannel` field to be set to `Application`. There is no need to provide additional browser details as in a web application. If processing a payment for a specific Sub-Account, make sure to include the `Account` header in your API request with the Sub-Account ID as its value. ## Handling the Result Upon a successful request, the API will respond with the payment result, which you can use to determine the outcome of the Server-To-Server payment. The response will include a `status` field indicating the current status of the payment. If the status is: - `Approved` or `Captured`: then the payment was successfully processed and you can show a confirmation message to the customer. - still `Pending`: then check the `lastError` property to see the details of the error and take appropriate action. You can find more information about handling errors in the [Handling SDK Errors](/documentation/get_started/process_payments/sdk_errors) page. - `PendingAction`: then the payment requires further action to be completed. In this case, the response will include a `requiredAction` object which needs to be handled accordingly. Please refer to the [Required Actions](/documentation/get_started/process_payments/embedded_sdk/additional_config#required-actions) page for more information on how to handle this scenario. ## Next Steps Once a payment is processed, you can get the final outcome of each payment asynchronously by listening to the relevant [webhooks](/documentation/get_started/webhooks).