RH API ## Sections • [API Overview](https://docs.rectanglehealth.com/rh_api/about-rectangle-health-apis.md): Rectangle Health APIs provide a flexible and secure way to process payments and manage transaction data across different payment scenarioes. Whether you're handling in-person payments through terminals or processing transactions online, our APIs are designed to support a seamless integration experience. Our platform offers dedicated APIs for both Card Present (CP) and Card Not Present (CNP) transactions, each tailored to its specific use case. In addition, the Transaction Reporting API and Card-on-File (CoF) API extend your ability to access transaction insights and manage stored payment methods. Explore the sections below to learn more about each API and how to integrate with Rectangle Health. Rectangle Health Pay - Card Present The Rectangle Health Pay - Card Present API supports in-person payment processing on supported PAX terminal devices. The API enables merchants to initiate standard sale and surcharge-enabled sale transactions by submitting a request to the gateway, which initializes the terminal to accept a card payment. A dedicated Rectangle Health payment application must be installed on the terminal device, replacing the legacy application. This application manages transaction processing and communication with the gateway, ensuring secure and streamlined payment handling at the point of sale. Rectangle Health Pay - Card Not Present The Rectangle Health Pay - Card Not Present API provides a secure and flexible way to process transactions without a physical card present. The API supports essential transaction workflows, including sale, void/refund, and partial void/refund. Sensitive payment data is secured through client-side encryption, while API key-based authentication ensures that all requests are properly authorized. This approach enables PCI-compliant integrations with minimal exposure to cardholder data. Transaction Reporting API The Transaction Reporting API allows a technology partner to offer their users access to transaction data for reporting and reconciliation purposes. This API enables retrieval of transaction history to support financial analysis and reporting workflows. Card-on-File (CoF) API The Card-on-File (CoF) API enables secure storage and management of customer payment information through tokenization. Sensitive payment data is replaced with a reusable payment token, allowing stored payment methods to be referenced without exposing actual card details. Businesses can create, retrieve, and delete stored payment methods, supporting use cases such as faster checkout experiences and recurring or repeat payments. The API ensures compliance with PCI DSS while providing a secure way to store and manage sensitive payment details. • [User Guide](https://docs.rectanglehealth.com/rh_api/user-guide.md): The User Guide section provides comprehensive instructions and guidelines for effectively utilizing the APIs within the project. Users can learn how to navigate the API's functionalities, understand its various features, and optimize their integration process for seamless operations. This section serves as a valuable resource for developers seeking clarity and guidance on leveraging the APIs to its full potential. • [About Your Credentials](https://docs.rectanglehealth.com/rh_api/user-guide/integration-guide/about-your-credentials.md): When integrating with Rectangle Health APIs, you receive several identifiers and credentials that establish authentication, determine where requests are processed, and define how different platform capabilities (such as payments, reporting, and wallet) function. Together, these identifiers connect your integration to the correct account and enable secure processing across all supported APIs. Each credential serves a specific purpose within the Rectangle Health platform. The credentials required, and how they are included in requests, vary depending on the API being used. Refer to the sections below for the credentials required by each API. Rectangle Health Pay - Card Present (CP) Terminal Serial Number - identifies the physical payment terminal. Purpose : Pre-configured mapping ensures transactions from a terminal are routed to the correct merchant account. Where Used : Required in request payload for Card Present transactions. Rectangle Health Pay - Card Not Present (CNP) API Key - Used to authenticate your application; must be included in the request headers. Merchant Account Code - Identifies the account where the transaction will be processed; must be included in the request body. Transaction Reporting API API Key - Used to authenticate your application; must be included in the request headers. Merchant Account Code - Identifies the account associated with the request; required for retrieving transaction data. Card-on-File (CoF) API API Key - Used to authenticate your application; must be included in the request headers. Merchant Account Code - Identifies the account associated with the stored payment data. • [Authentication](https://docs.rectanglehealth.com/rh_api/user-guide/integration-guide/authentication.md): Rectangle Health APIs use different authentication methods depending on the API. Authentication ensures that requests are securely processed and routed to the appropriate merchant account. Refer to the sections below for authentication requirements by API. Rectangle Health Pay - Card Present (CP) The Rectangle Health Pay - Card Present API is used for transactions initiated from physical payment terminials. During onboarding, the gateway account and terminal device are securely configured and mapped within the Rectangle Health platform. This ensures that each terminal is associated with the correct merchant account. Authentication Method Provide the terminal serial number in the request payload. Base URL Sandbox : https://services-sandbox.rectanglehealth.com Production: https://services.rectanglehealth.com Integration Perspective The platform identifies the terminal using the serial number. The associated merchant account is determined based on the terminal configuration. The transaction is processed under the correct account automatically. No additional credentials (such as API Keys or Merchant Account Numbers) are required for Card Present transactions. Rectangle Health Pay - Card Not Present (CNP) The Rectangle Health Pay - Card Not Present API is used for transactions where the card is not physically present (e.g., online or virtual transactions). Authentication Method The following credentials are required for each request: API Key - Must be included in the request headers to authenticate the calling application. Merchant Account Code - Must be included in the request body to specify the merchant account for processing. Base URL Sandbox : https://api.qa.rectangle.health/cipherpay Production: https://api.rectangle.health/cipherpay Integration Perspective The API Key identifies who is making the request. The Merchant Account Code identifies which account should process the transaction. Both are required for successful Card Not Present transaction processing. For CNP transaction processing, payment data must be encrypted using our provided script to ensure secure transmission. Please fine more details and examples here: Payment Encryption . Transaction Reporting API The Transaction Reporting API allows you to retrieve detailed transaction data for your account. Authentication Method The following credential is required for each request: API Key - Must be included in the request headers to authenticate the calling application. Base URL Sandbox : https://api.qa.rectangle.health/cipherpay Production: https://api.rectangle.health/cipherpay Integration Perspective The API Key identifies who is making the request. The request is authorized based on the API key. Additional parameters (such as invoice number or transaction ID) are used to retrieve transaction data. Card-on-File (CoF) API The Card-on-File API enables management of stored payment methods. Authentication Method The following credential is required for each request: API Key - Must be included in the request headers to authenticate the calling application. Base URL Sandbox : https://api.qa.rectangle.health/cipherpay Production: https://api.rectangle.health/cipherpay Integration Perspective The API Key identifies who is making the request. The Merchant Account Code specifies the account associated with the stored payment data. The token reference is used to identify stored payment tokens for retrieval or deletion. For payment token creation, sensitive payment data must be encrypted using the provided client-side encryption method. Refer to the Payment Encryption guide for details and examples. • [Test Information](https://docs.rectanglehealth.com/rh_api/user-guide/test-information.md): This Test Information section provides detailed metadata about test executions within the RH API environment. It enables users to validate and troubleshoot their integrations by accessing comprehensive test-related information, helping ensure accuracy, reliability, and readiness before going live. • [Test Amount Range](https://docs.rectanglehealth.com/rh_api/user-guide/test-information/test-amount-range.md): To support testing different transaction scenarios, the API uses the cent value of the transaction amount to determine the response type. By adjusting the cents portion of the amount, you can simulate various authorization outcomes. How It Works When submitting a transaction in the test environment, modify the last two digits (cents) of the amount to trigger specific response. You can find the test card numbers in Test Account Information . Ending Cents Response Type Notes .01 Decline Standard decline .02 Referral Declined by issuer; customer action required .03 CVV Failure (Conditional) Decline (CNP), Approved (CP) .04 Timeout Standard timeout .14 Partial Authorization 50 % of amount approved Other Approved Full authorization • [Test Account Information](https://docs.rectanglehealth.com/rh_api/user-guide/test-information/test-account-information.md): The Test Account Information section provides access to test cards and bank accounts for simulating payment transactions in a controlled environment. Users can use these test accounts to validate their integration with the API and ensure that their payment processing workflow functions correctly before going live. Test Cards & Bank Accounts For AMEX, use CVV values of 1234 or 1111. For all others card brands, use CVV values of 999 or 111. For PIN transactions, the PIN is usually the last four of the test card number or 1234. The following accounts will be accepted by the test server's validation merchanism and thus can be used for certification testing: Card Type Card Brand Card Number Expiration Date Credit Visa 4000020000000000 1230 Credit MasterCard 5001650000000000 1230 Credit Discover 6011000000000004 1230 Credit Amex 3400000000000000 1230 Debit Visa 4701322211111234 1230 Debit MasterCard 5100270000000007 1230 Bank Account Bank Account Number Routing Number 4099999992 021000021 • [Gateway References](https://docs.rectanglehealth.com/rh_api/user-guide/gateway-references.md): The Gateway References section provides detailed information about payment gateways integrated within the RH API. Users can retrieve and explore gateway-specific metadata to seamlessly manage payment processing configurations and ensure smooth transaction workflows. • [AVS/CVV Responses](https://docs.rectanglehealth.com/rh_api/user-guide/gateway-references/avs-cvv-responses.md): The AVS/CVV Responses document provides detailed information on Address Verification Service (AVS) and Card Verification Value (CVV) responses. AVS Responses: Code Message A Address (Street) matches , ZIP does not. B Address (Street) matches, ZIP not verified. E AVS error. G Non-U.S. Issuer does not participate. N No Match on Address (Street) or ZIP. O No Match on Address (Street) or ZIP. P ZIP matches, Address (Street) not verified. R Retry, System unavailable or Timed out. S Service not supported by issuer. U Address information is unavailable. W 9 digit ZIP matches, Address (Street) does not. X Exact AVS Match. Y Address (Street) and 5 digit ZIP match. Z 5 digit ZIP matches, Address (Street) does not. AVS result codes are for indication to the merchant only, and do not influence the overall authorisation result. CVV Responses: Code Message M CVV Match N CVV No Match P Not Processed S CVV should be on the card but the merchant indicates it is not U User is unregistered • [Bank (Issuer) Response Codes](https://docs.rectanglehealth.com/rh_api/user-guide/gateway-references/bank-response-codes.md): The Bank Response Codes document provides detailed information on issuer response codes returned during payment processing. These two-digit codes indicate the reason a transaction was approved or declined, helping users better understand the outcome of a payment attempt. Note : The bank (issuer) response code is returned in the response_code field of the API response. The list below includes the most common response codes provided by issuers. However, response codes and their meaning may vary depending on the issuing bank. Code Description 00 Approved, authorized 01 Refer to card issuer 02 Refer to issuer's special conditions 03 Invalid merchant or service provider 04 Pick up card 05 Do not honor 06 Error 07 Pick up, special condition (other than lost/stolen) 08 Honor with ID 09 Request in progress 10 Partial amount approved 11 VIP Approval 12 Invalid or expired transaction 13 Invalid amount 14 Invalid card/account number 15 No such issuer 16 Approved, update track 3 17 Customer cancellation 18 Customer dispute 19 Re-enter transaction 20 Invalid response 21 No action taken (no match) 22 Suspected malfunction 23 Unacceptable transaction fee 24 File update not supported by receiver 25 Unable to locate record on file 26 Duplicate file update record 27 File update field edit error 28 File update file locked out 29 File update not successful 30 Format error 31 Bank not supported by switch 32 Completed partially 33 Expired card - pick up 34 Suspected fraud - pick up 35 Contact acquirer - pick up 36 Restricted card - pick up 37 Call acquirer security - pick up 38 Allowable pin tries exceeded 39 No credit account 40 Requested function not supported 41 Lost card - pick up 42 No universal amount 43 Stole card - pick up 44 No investment account 46 Closed account 51 Insufficient funds 52 No checking account 53 No savings account 54 Expired card or invalid expiration date 55 Incorrect pin 56 No card record 57 Transaction not permitted to cardholder 58 Transaction not permitted to terminal 59 Suspected fraud 60 Card acceptor contact acquirer 61 Exceeds withdrawal limit 62 Invalid service code, restricted 63 Security violation 65 Activity limit exceeded 66 Card acceptor call acquirer security 67 Hard capture - pick up card at ATM 68 Response received too late 70 PIN data required 75 PIN tries exceeded 76 Unable to locate, no match 77 Inconsistent data, rev., or repeat 78 No account 79 Already reversed at switch 80 Invalid date 81 Cryptographic failure 82 Incorrect CVV 83 Unable to verify PIN 84 Invalid authorisation life cycle 85 No reason to decline 86 ATM malfunction 87 No envelope inserted 88 Unable to dispense 89 Administration error 90 Cut-off in progress 91 Issuer or switch is unavailable 92 Destination not found 93 Violation, cannot complete 94 Duplicate transmission 95 Reconcile error 96 System malfunction 97 Reconciliation totals reset 98 MAC error A1 POS device authentication successful A2 POS device authentication not successful A3 POS device deactivation successful B1 Surcharge amount not permitted on Visa Cards or EBT food stamps B2 Surcharge amount not supported by debit network issuer CV Card type verification error E1 Encryption not configured E2 Terminal not authenticated E3 Data could not be decrypted EA Account length error EB Check digit error EC CID format error HV Hierarchy verification failure IA Additional customer authentication required K0 Token request was processed K1 Tokenization Not Configured K2 Terminal not authenticated K3 Data could not be de-tokenized N0 Force STIP N3 Cash service is not available N4 Cash request exceeds issuer limit N5 Ineligible for re-submission N7 Decline for CVV2 failure N8 Transaction amount exceeds pre-authorized amount P0 Approved; PVID is missing, invalid or expired P1 Declined; PVID is missing, invalid or expired P2 Invalid biller information P5 PIN change unblock declined P6 Unsafe PIN R0 Customer requested stop of specific recurring payment R1 Revocation of authorization order R3 Revocation of all authorizations order T0 First check is OK and has been converted T1 Check is OK but cannot be converted - declined transaction T2 Invalid ABA number, not an ACH participant T3 Amount greater than the limit T4 Unpaid items, failed negative file check T5 Duplicate check number T6 MICR error T7 Too many checks (over merchant or bank limit) V1 Failure VM Q1 Card authentication failed XA Forward to issuer XD Forward to issuer Z3 Unable to go online • [Gateway Response Codes](https://docs.rectanglehealth.com/rh_api/user-guide/gateway-references/gateway-response-codes.md): The Gateway Response Codes document provides detailed information on the various response codes that can be received from the gateway. Users can reference these codes to better understand the outcome of their API requests and troubleshoot any potential issues that may arise during transaction processing. Note : The gateway response code is returned in the result_code field of the API response. Code Message Description A Approval The transaction has been authorized. When an approval code is returned, a hold will be placed on cardholder funds in the amount of the sale (depending on the card issuing bank it might take a different number of days) and will guarantee funds to be transferred into a merchant’s account. D Declined The bank has declined the transaction and funds will not be transferred into the merchant's account. C Pick Up The card issuer has declined the transaction and requested that the card be retained as it may have been reported as lost or stolen. R Referral The bank requires more information before they can approve the transaction. This is only relevant when processing Mail/Telephone Order transactions through our Virtual Terminal. If you get an R (Referral) response code, you should contact your acquiring bank immediately, because once these transactions settle, they can no longer be completed. You will be asked for the transaction details and then an authorization code will be provided. • [Workflows](https://docs.rectanglehealth.com/rh_api/user-guide/workflow.md): The Workflows section provides detailed step-by-step guides for using our API, covering processes such as payment tokenization, transaction processing, wallet management, and other key fuctionalities. Each workflow is designed to help developers understand how to implement and integrate specific API operations effectively. • [Card-on-File (CoF) API Workflow](https://docs.rectanglehealth.com/rh_api/user-guide/workflow/cof-api-workflow.md): The Card-on-File (CoF) API enables merchants to securely store customer payment credentials and process future transactions without requiring card data to be re-entered for every payment. The Card-on-File (CoF) API uses encrypted payment data along with tokenized payment reference ( payment_token ) or merchant-assigned cof_reference values to help reduce exposure to sensitive payment information while supporting recurring and future card-not-present payment transactions. 1 Encrypt Payment Data Before payment information can be stored, the payment data must first be encrypted using the Payment Encryption script. The Payment Encryption script securely encrypts sensitive cardholder data before it is transmitted to the Card-on-File service. The encrypted resposne returned from this script is used as the encrypted_card_data value when creating a Card-on-File. Purpose of Encryption Encrypting payment data helps: Protect sensitive cardholder information during transmission Reduce exposure to raw payment card data Support secure card-not-present payment workflows Ensure payment data is tokenized before storage or processing The response returned from the script should look like the following: JSON {"encrypted_card_data":{"kid":"d29775d4-fc38-425b-a38d-bf9a253a0a2c","ciphertext_b64":"M6OBgZ6svvbGi3nrB3r5ftG2ogWfGNaNcb8DbsnzeFZ19fha3oq7tfwr0zsISK8cU7nrEKTDVOrXYuRk9+dGYXOfil3XOCVHXzIsrxVnfQ5v08Fjd5sJD42AEGre7WzFTOKlkcEz7iwRzyYxgZiUhnQxasnIQYHco5kxpeaur/aqsHyJqdF6+oVHMw+HZewBu/F6cIeaLqUFvVoajVg4JW5SN3txUY9/0bpAfHIVZ2QPSZmq6Hm0/dmVuFfis3374Jxjpi6QH8p44tBIhV36s3wADZa9iS+jdPj3C+8SFJZoGIw7uVkeGB3ROyf/fIUUUhxLd4hQc8MG0G0xTcyz2g==","nonce":"NBOetRZbMh3LDfbMrNfCPwC1qJV5iUOT","issued_at":1776187237,"expires_at":1776187297}} The encrypted_card_data received in the response represents the customer's payment method and should be provided when creating a Card-on-File (CoF). 2 Create a Card-on-File (CoF) After the payment information has been encrypted, create a Card-on-File record using the encrypted payment data. Reference : Create Card-on-File (CoF) Endpoint: /api/v1/card_on_file Request Body : Please note that x-api-key must be included in the request headers as it is used as authentication for the Card-on-File (CoF) API. JSON { "encrypted_card_data": {{encrypted_card_data}}, "merchant_account_code": "{{merchant_account_code}}", "cof_reference": "rh-test-cof", "account_holder": { "name": "Firsty Lasty", "street": "123 Street", "city": "City", "state": "NY", "zip": "12345", "country_code": "US" } } if cof_reference is not provided, our system will automatically generate and assign it. Response: JSON { "merchant_account_code": "6374001", "cof_reference": "rh-test-cof", "payment_token": "2967536759278781", "expiration_date": "1231", "masked_pan": "476173******0043", "card_type": "VISA", "card_identifier": "CREDIT", "account_holder_name": "Firsty Lasty", "customer_address_line1": "123 Street", "customer_city": "City", "customer_state": "NY", "customer_zip": "12345", "metadata": { "correlation_id": "abc95fa3-5fcc-41da-b8af-01bafe54dcf1", "timestamp": "2026-05-07T04:13:04.120781+00:00" } } Both cof_reference and payment_token act as the unique identifier for the stored payment method and are used for future payment transacitons. cof_referecne - a client-provided custom ID for the CoF record. It must be unique per Merchant Account Code (MAC) . The same cof_reference cannot be reused . Even if a Card-on-File is deleted or becomes inactive, the original cof_reference cannot be reused for a new creation because it is tied to existing transactions in our system and is retained internally for data integrity and future refund functionality. payment_token - a uniquie ID generated by the API for the CoF record. 3 Process Payments Using Stored Payment Credentials After a Card-on-File (CoF) has been created, future transactions can be processed without requiring the customer to re-enter payment information. Payments can be processed using either: CoF Reference Payment Token This allows merchants to support streamlined checkout experiences and recurring or future card-not-present transactions. A. Sale via CoF Reference The cof_reference provides a merchant-controlled identifier that maps to the stored payment method associated with the customer. Reference : Sale via Card-on-File (CoF) Endpoint : /api/v1/pay Request Body : Please note that x-api-key must be included in the request headers as it is used as authentication for the RH Pay (CNP) API. JSON { "cof_reference": "{{cof_reference}}", "amount": "5.00", "transaction_type": "sale", "merchant_account_code": "{{merchant_account_code}}", "inv_num": "{{inv_num}}", "accept_partial_amount": true, "non_surcharge": true } Response : JSON { "data": { "device_serial_number": null, "merchant_account_code": "6374001", "merchant_name": "Rectangle", "last_four": "0043", "card_bin": "476173", "masked_pan": "476173******0043", "card_type": "VISA", "cvv_result": "", "avs_result": "U", "account_holder_name": "Firsty Lasty", "entry_mode": "KEYED", "expiration_date": "1231", "settle_amount": 500, "fee_amount": 0, "net_amount": 500, "requested_amount": 500, "customer_address_line1": null, "customer_city": null, "customer_state": null, "customer_zip": null, "payment_token": "", "card_identifier": "CREDIT", "auth_code": "016482", "result_code": "A", "result_message": "APPROVED", "transaction_id": "IAG966YORZ", "inv_num": "RH_565_8", "sale_date_time": "20260507002656", "transaction_type": "SALE", "response_message": "APPROVAL", "status": "Confirmed" }, "metadata": { "correlation_id": "72b379e8-b98e-4900-bee4-eb13bd989a98", "timestamp": "2026-05-07T04:26:56.562102+00:00" } } B. Sale via Payment Token The payment_token represents the securely stored payment method and can be submitted during payment processing instead of raw card data. Reference : Sale via Payment Token Endpoint : /api/v1/pay Request Body : Please note that x-api-key must be included in the request headers as it is used as authentication for the RH Pay (CNP) API. JSON { "payment_token": "{{payment_token}}", "amount": "5.00", "transaction_type": "sale", "merchant_account_code": "{{merchant_account_code}}", "inv_num": "{{inv_num}}", "accept_partial_amount": true, "non_surcharge": true } Response : JSON { "data": { "device_serial_number": null, "merchant_account_code": "6374001", "merchant_name": "Rectangle", "last_four": "0043", "card_bin": "476173", "masked_pan": "476173******0043", "card_type": "VISA", "cvv_result": "", "avs_result": "U", "account_holder_name": "Firsty Lasty", "entry_mode": "KEYED", "expiration_date": "1231", "settle_amount": 500, "fee_amount": 0, "net_amount": 500, "requested_amount": 500, "customer_address_line1": null, "customer_city": null, "customer_state": null, "customer_zip": null, "payment_token": "", "card_identifier": "CREDIT", "auth_code": "312605", "result_code": "A", "result_message": "APPROVED", "transaction_id": "DSPF3NH9TY", "inv_num": "RH_442_259", "sale_date_time": "20260507003152", "transaction_type": "SALE", "response_message": "APPROVAL", "status": "Confirmed" }, "metadata": { "correlation_id": "4cc79773-a0db-483d-b4a3-50c49e37d90e", "timestamp": "2026-05-07T04:31:52.682707+00:00" } } 4 Manage Card-on-File (CoF) Records The Card-on-File API supports retrieving and deleting existing Card-on-File records. Payment Method Change Workflow When a customer updates their payment information , the recommended workflow is: Retrieve the existing Card-on-File if needed Delete the existing Card-on-File Submit the updated payment information through the Payment Encryption script Create a new Card-on-File using the newly generated encrypted_card_data and a new unique cof_reference Because cof_reference values cannot be reused , a new unique reference must always be generated when creating a replacement Card-on-File. The Card-on-File API supports secure management of stored payment credentials. Refer to the Card-on-File API documentation for additional details on supported operations and implementation requirements. By following this workflow, merchants can securely store customer payment credentials and process future card-not-present transactions using securely stored payment references. • [Surcharge Workflow](https://docs.rectanglehealth.com/rh_api/user-guide/workflow/surcharge-workflow.md): This document describes how surcharging is applied to both Card-Presnet (CP) and Card-Not-Present (CNP) transactions within the Rectangle Health payment ecosystem. It outlines the required configuration, workflow in detail, API request and response behavior, and transaction handling. It is the responsibility of the practice to implement surcharging in compliance with applicable laws and to remain up to date with state-specific regulations and limitations . Overview Surcharging is the practice of adding a fee to credit card transactions to offset processing costs. Rectangle Health supports surcharging for both: Card-Present (CP) transactions Card-Not-Present (CNP) transactions Both transaction types are processed through Rectangle Health Pay (Card-Present and Card-Not-Present). Debit, prepaid, and EBT cards cannot be surcharged. Pre-requisites Before implementing surcharging, ensure the following requirements are met. Card-Present (CP) The gateway account is configured with surcharge enabled. The terminal device is onboarded and configured in the Rectangle Health system with the corresponding gateway information. The Rectangle Health Pay (RH Pay) application is properly installed on the terminal device. Surcharge Confirmation Prompt is enabled to require customer or merchant acknowledgment before processing the transaction. Card-Not-Present (CNP) The gateway account is configured with surcharge enabled. Access to Rectangle Health Pay - Card Not Present endpoints is available. Surcharging Workflows Surcharge behavior for both CP and CNP transactions is controlled using the nonSurcharge field. While the same control applies to all transaction types, surcharge calculation differs between sale and void/refund workflows. A. Sales with Surcharge The sale workflow is consistent for both CP and CNP transactions. When surcharge is enabled for an account: The nonSurcharge field controls whether a surcharge is applied. By default, nonSurcharge is false , meaning the surcharge is applied. If the field is not provided, the transaction is processed with a surcharge by default. To prevent a surcharge: Set nonSurcharge to true in the request payload. If surcharge is not enabled on the account, it will not be applied regardless of the nonSurcharge value. Surcharge Calculation The surcharge is automatically calculated based on the configured percentage during onboarding. The calculated surcharge is added to the base amount to determine the total transaction amount. No surcharge calculation is required on the integrator side for sale transactions. Notes Surcharge must be enabled on the account for it to apply. nonSurcharge is only required when explicitly preventing a surcharge. Surcharge is not supported for partial authorization at this time. API Examples [ Card Present ] Base URL : https://services-sandbox.rectanglehealth.com (UAT) Endpoint : POST /req/payment Example Request : JSON { "terminalID": "{{terminalID}}", "mode": "UAT", "amount": "40.00", "invNum": "{{invNum}}", "tenderType": "CREDIT", "transType": "SALE", "acceptPartialAmount": true, "nonSurcharge": false } Example Response: JSON { "requestID": "173e01c8-05e7-4a01-bf4b-4edb3c95729c", "locationID": "b9cdf5cb-a8cd-43f9-9653-912e05dd93b2", "terminalID": "b9cdf5cb-a8cd-43f9-9653-912e05dd93b2", "approvedAmount": "4120", "authCode": "307546", "cardType": "VISA", "cardHolderName": "Firsty Lasty", "cashBackAmt": "0", "entryMode": "KEYED", "expirationDate": "0228", "extData": { "receiptTagData": { "maskedCard": "411111******1111", "chipCardAID": "NA", "atc": "7KPU", "invoice": "rh_460_337", "authCode": "307546", "entryMethod": "KEYED", "totalAmount": "4120", "appLabel": "VISA CREDIT" }, "signatureEncoded": "YzVlM2QzZmE4OThjNjE5OTJmMTQ5MjBmY2RkMGM1OTdkNjBkNDQ3NjkxNDQ2Mjk1NjIxZjM4YjFkMTMwMGViODQxNTI5NGIzMGU4OWVkYTI1YTJkODAwZDE5MzZiZTkyYzIxODZlN2ViY2U3YTE4M2EyOTNhNzE0OGYyMDA0YWVlYWM4NTA1NWZiOWI0NTRhYjdiN2NiOThiNzk4NTFjZDFlODAyY2UzZDJjMzdkMzZjODA2ZWNiMTQ4OGNmMTJkYjM1MTkxYTc0MmNkM2YxMGIyN2UxZmUyMTdmOTQ5ZmRhNmFkYzBiYWI2NzJlNzI1ODA5NzRhMzgzZDg3NjQzMw==" }, "gatewayMessage": "APPROVAL", "gatewayResult": "000000", "sourceResponseMessage": "APPROVAL", "hostCode": "FIYQ9TKPMZ", "hostResponse": "00000", "invNum": "rh_460_337", "maskedAccountNumber": "411111******1111", "message": "Approved, authorized", "pnRefNum": "FIYQ9TKPMZ", "rawResponse": "Y3VzdG9tZXJfYWNjb3VudD1QYXlyb2NDdXN0b21lckFjY291bnQoY2FyZF90eXBlPSdWaXNhIENyZWRpdCcsIGNhcmRob2xkZXJfbmFtZT0nTkEnLCBlbnRyeV9tZXRob2Q9J0tFWUVEJywgZXhwaXJ5X2RhdGU9JzAyMjgnLCBtYXNrZWRfcGFuPSc0MTExMTEqKioqKioxMTExJykgZW12X3RhZ3M9W10gbGlua3M9W1BheXJvY1BheW1lbnRSZXF1ZXN0TGluayhyZWw9J3JlZnVuZCcsIG1ldGhvZD0nUE9TVCcsIGhyZWY9SHR0cFVybCgnaHR0cHM6Ly90ZXN0cGF5bWVudHMud29ybGRuZXR0cHMuY29tL21lcmNoYW50L2FwaS92MS90cmFuc2FjdGlvbi9wYXltZW50cy9GSVlROVRLUE1aL3JlZnVuZHMnKSksIFBheXJvY1BheW1lbnRSZXF1ZXN0TGluayhyZWw9J3VwZGF0ZScsIG1ldGhvZD0nUEFUQ0gnLCBocmVmPUh0dHBVcmwoJ2h0dHBzOi8vdGVzdHBheW1lbnRzLndvcmxkbmV0dHBzLmNvbS9tZXJjaGFudC9hcGkvdjEvdHJhbnNhY3Rpb24vcGF5bWVudHMvRklZUTlUS1BNWicpKSwgUGF5cm9jUGF5bWVudFJlcXVlc3RMaW5rKHJlbD0nY2FwdHVyZScsIG1ldGhvZD0nUEFUQ0gnLCBocmVmPUh0dHBVcmwoJ2h0dHBzOi8vdGVzdHBheW1lbnRzLndvcmxkbmV0dHBzLmNvbS9tZXJjaGFudC9hcGkvdjEvdHJhbnNhY3Rpb24vcGF5bWVudHMvRklZUTlUS1BNWi9jYXB0dXJlJykpLCBQYXlyb2NQYXltZW50UmVxdWVzdExpbmsocmVsPSdyZXZlcnNlJywgbWV0aG9kPSdQQVRDSCcsIGhyZWY9SHR0cFVybCgnaHR0cHM6Ly90ZXN0cGF5bWVudHMud29ybGRuZXR0cHMuY29tL21lcmNoYW50L2FwaS92MS90cmFuc2FjdGlvbi9wYXltZW50cy9GSVlROVRLUE1aL3JldmVyc2UnKSldIG9wZXJhdG9yPSdSZWN0YW5nbGUgSGVhbHRoJyBvcmRlcj1QYXlyb2NSZXNwb25zZU9yZGVyKGN1cnJlbmN5PTxDdXJyZW5jeS5VU0Q6ICdVU0QnPiwgb3JkZXJfaWQ9J3JoXzQ2MF8zMzcnLCB0b3RhbF9hbW91bnQ9RGVjaW1hbCgnNDEuMicpLCBvcmRlcl9icmVha2Rvd249UGF5cm9jT3JkZXJCcmVha2Rvd24oc3VidG90YWxfYW1vdW50PURlY2ltYWwoJzQwLjAwJyksIHN1cmNoYXJnZT1QYXlyb2NTdXJjaGFyZ2UoYnlwYXNzPUZhbHNlLCBhbW91bnQ9RGVjaW1hbCgnMS4yJykpKSkgcmVjZWlwdHM9W1BheXJvY1JlY2VpcHQocmVjZWlwdF9jb3B5PSdDQVJESE9MREVSX0NPUFknLCBjdXN0b21fZmllbGRzPVtdLCBmb290ZXI9J1BMRUFTRSBSRVRBSU4gRk9SIFlPVVIgUkVDT1JEUycsIGhlYWRlcj0nQ0FSREhPTERFUiBDT1BZJywgaWNjX2RhdGE9W10sIG1lcmNoYW50X2RldGFpbHM9W1BheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdDb21wYW55Jywgb3JkZXI9MCwgdmFsdWU9J1JlY3RhbmdsZScpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nQWRkcmVzcycsIG9yZGVyPTEsIHZhbHVlPSdUZXN0IEFkZHJlc3MgMSwgVGVzdCBBZGRyZXNzIDIsIFVuaXRlZCBTdGF0ZXMnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1Bob25lJywgb3JkZXI9MiwgdmFsdWU9JzEyMzQ1Njc4OTAnKV0sIHRyYW5zYWN0aW9uX2RhdGE9W1BheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdDYXJkIGFjY2VwdG9yIG51bWJlcicsIG9yZGVyPTAsIHZhbHVlPScqKioqKioqODk4ODQnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J0RhdGUvVGltZScsIG9yZGVyPTEsIHZhbHVlPSdNYXIgMTksIDIwMjYsIDE6NTE6NDcgUE0nKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1RyYW5zYWN0aW9uIERhdGEgU291cmNlJywgb3JkZXI9MiwgdmFsdWU9J0tFWUVEJyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdUcmFuc2FjdGlvbicsIG9yZGVyPTMsIHZhbHVlPSdQdXJjaGFzZScpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nVHlwZScsIG9yZGVyPTQsIHZhbHVlPSdDdXN0b21lciBQcmVzZW50JyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdTdGF0dXMnLCBvcmRlcj01LCB2YWx1ZT0nUkVBRFknKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J0NhcmQnLCBvcmRlcj02LCB2YWx1ZT0nNDExMTExKioqKioqMTExMSAwMi8yOCAoVmlzYSBDcmVkaXQpJyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdBdXRoIFJlc3BvbnNlJywgb3JkZXI9NywgdmFsdWU9J0FQUFJPVkFMJyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdBdXRob3Jpc2F0aW9uIENvZGUnLCBvcmRlcj04LCB2YWx1ZT0nMzA3NTQ2JyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdBbW91bnQnLCBvcmRlcj05LCB2YWx1ZT0nVVNEIDQwLjAwJyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdTdXJjaGFyZ2UgRmVlJywgb3JkZXI9MTAsIHZhbHVlPSdVU0QgMS4yMCcpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nVG90YWwgQW1vdW50Jywgb3JkZXI9MTEsIHZhbHVlPSdVU0QgNDEuMjAnKV0pLCBQYXlyb2NSZWNlaXB0KHJlY2VpcHRfY29weT0nQ0FSRF9BQ0NFUFRPUl9DT1BZJywgY3VzdG9tX2ZpZWxkcz1bXSwgZm9vdGVyPSdQTEVBU0UgREVCSVQgTVkgQUNDT1VOVCBXSVRIIFRPVEFMIFNIT1dOJywgaGVhZGVyPSdNRVJDSEFOVCBDT1BZJywgaWNjX2RhdGE9W10sIG1lcmNoYW50X2RldGFpbHM9W1BheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdDb21wYW55Jywgb3JkZXI9MCwgdmFsdWU9J1JlY3RhbmdsZScpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nQWRkcmVzcycsIG9yZGVyPTEsIHZhbHVlPSdUZXN0IEFkZHJlc3MgMSwgVGVzdCBBZGRyZXNzIDIsIFVuaXRlZCBTdGF0ZXMnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1Bob25lJywgb3JkZXI9MiwgdmFsdWU9JzEyMzQ1Njc4OTAnKV0sIHRyYW5zYWN0aW9uX2RhdGE9W1BheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdDYXJkIGFjY2VwdG9yIG51bWJlcicsIG9yZGVyPTAsIHZhbHVlPSc0OTgzMjI1ODk4ODQnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J09yZGVyIElEJywgb3JkZXI9MSwgdmFsdWU9J3JoXzQ2MF8zMzcnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1VuaXF1ZSBSZWYnLCBvcmRlcj0yLCB2YWx1ZT0nRklZUTlUS1BNWicpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nRGF0ZS9UaW1lJywgb3JkZXI9MywgdmFsdWU9J01hciAxOSwgMjAyNiwgMTo1MTo0NyBQTScpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nVHJhbnNhY3Rpb24gRGF0YSBTb3VyY2UnLCBvcmRlcj00LCB2YWx1ZT0nS0VZRUQnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1RyYW5zYWN0aW9uJywgb3JkZXI9NSwgdmFsdWU9J1B1cmNoYXNlJyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdUeXBlJywgb3JkZXI9NiwgdmFsdWU9J0N1c3RvbWVyIFByZXNlbnQnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1N0YXR1cycsIG9yZGVyPTcsIHZhbHVlPSdSRUFEWScpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nQ2FyZCcsIG9yZGVyPTgsIHZhbHVlPSc0MTExMTEqKioqKioxMTExIDAyLzI4IChWaXNhIENyZWRpdCknKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J0F1dGggUmVzcG9uc2UnLCBvcmRlcj05LCB2YWx1ZT0nQVBQUk9WQUwnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J0F1dGhvcmlzYXRpb24gQ29kZScsIG9yZGVyPTEwLCB2YWx1ZT0nMzA3NTQ2JyksIFBheXJvY1JlY2VpcHRMaW5lKGxhYmVsPSdBbW91bnQnLCBvcmRlcj0xMSwgdmFsdWU9J1VTRCA0MC4wMCcpLCBQYXlyb2NSZWNlaXB0TGluZShsYWJlbD0nU3VyY2hhcmdlIEZlZScsIG9yZGVyPTEyLCB2YWx1ZT0nVVNEIDEuMjAnKSwgUGF5cm9jUmVjZWlwdExpbmUobGFiZWw9J1RvdGFsIEFtb3VudCcsIG9yZGVyPTEzLCB2YWx1ZT0nVVNEIDQxLjIwJyldKV0gc2VjdXJpdHlfY2hlY2s9UGF5cm9jU2VjdXJpdHlDaGVjayhhdnNfcmVzdWx0PSdVJykgc3VwcG9ydGVkX29wZXJhdGlvbnM9WydDQVBUVVJFJywgJ0ZVTExZX1JFVkVSU0UnLCAnUEFSVElBTExZX1JFVkVSU0UnLCAnSU5DUkVNRU5UX0FVVEhPUklaQVRJT04nLCAnQUREX1NJR05BVFVSRScsICdTRVRfQVNfUEVORElORyddIHRlcm1pbmFsPSc2Mzc0MDAxJyB0cmFuc2FjdGlvbl9yZXN1bHQ9UGF5cm9jVHJhbnNhY3Rpb25SZXN1bHQoYXBwcm92YWxfY29kZT0nMzA3NTQ2JywgYXV0aG9yaXplZF9hbW91bnQ9RGVjaW1hbCgnNDEuMicpLCBjdXJyZW5jeT08Q3VycmVuY3kuVVNEOiAnVVNEJz4sIGRhdGVfdGltZT0nMjAyNi0wMy0xOVQxMzo1MTo0Ny0wNTowMCcsIHByb2Nlc3Nvcl9yZXN1bHRfY29kZT0nMDAnLCByZXN1bHRfY29kZT0nQScsIHJlc3VsdF9tZXNzYWdlPSdBUFBST1ZBTCcsIHN0YXR1cz0nUkVBRFknLCB0eXBlPSdTQUxFJywgc3RvcmVkX3BheW1lbnRfY3JlZGVudGlhbHM9UGF5cm9jU3RvcmVkUGF5bWVudENyZWRlbnRpYWxzKHRlcm1pbmFsPSc2Mzc0MDAxJywgdXNhZ2VfYWdyZWVtZW50PSdVTlNDSEVEVUxFRCcsIG1lcmNoYW50X3JlZmVyZW5jZT0ncmhfNDYwXzMzNycsIGNhcmRob2xkZXJfbmFtZT1Ob25lLCBjcmVkZW50aWFsc19udW1iZXI9JzI5Njc1MzkyNDEyODQ4MDUnLCBtYXNrZWRfcGFuPSc0MTExMTEqKioqKioxMTExJywgc2VjdXJpdHlfY2hlY2s9J0NWVl9WQUxJREFURUQnLCBjdXN0b21lcj1QYXlyb2NDdXN0b21lcihyZWZlcmVuY2VfbnVtYmVyPScyOTY3NTM5MjQxMjg0ODA1Jywgbm90aWZpY2F0aW9uX2xhbmd1YWdlPSdlbicpKSkgdW5pcXVlX3JlZmVyZW5jZT0nRklZUTlUS1BNWic=", "refNum": "FIYQ9TKPMZ", "remainingAmount": "0", "requestedAmount": "4120", "feeAmount": "120", "netAmount": "4000", "resultCode": "000000", "resultTxt": "OK", "submittedAmount": "4120", "timestamp": "20260319135147", "tipAmount": "0", "token": "2967539241284805", "transactionCode": "FIYQ9TKPMZ", "metadata": { "timestamp": "2026-03-19T18:51:49.196721+00:00", "correlation_id": "173e01c8-05e7-4a01-bf4b-4edb3c95729c" } } [ Card Not Present ] Base URL : https://api.qa.rectangle.health/cipherpay (UAT) Endpoint : POST /api/v1/pay Example Request : JSON { "encrypted_card_data": "{{encrypted_card_data}}", "amount": "30.00", "transaction_type": "sale", "merchant_account_code": "{{merchant_account_code}}", "inv_num": "{{inv_num}}", "accept_partial_amount": true, "non_surcharge": false, "account_holder": { "name": "Test Name", "street": "street", "city": "city", "state": "WA", "zip": "12345", "country_code": "US", "phone": "1231231234", "email": "test@rectanglehealth.com" } } No surcharge field is required in the request. If surcharge is enabled for the account, the system automatically calculates the surcharge using the configured percentage and applies it to the transaction. Example Response: JSON { "data": { "device_serial_number": null, "merchant_account_id": "6374001", "merchant_name": "Rectangle", "last_four": "0043", "card_bin": "476173", "masked_pan": "476173******0043", "card_type": "VISA", "cvv_result": "M", "avs_result": "U", "account_holder_name": "Test Name", "entry_mode": "KEYED", "expiration_date": "1231", "settle_amount": 2000, "fee_amount": 0, "net_amount": 2000, "requested_amount": 2000, "customer_address_line1": "street", "customer_city": "city", "customer_state": "WA", "customer_zip": "12345", "payment_token": "2967531209136523", "card_identifier": "CREDIT", "auth_code": "454078", "result_code": "A", "transaction_id": "JWEALSYOAF", "invoice_number": "253_448", "sale_date_time": "20260324093733", "transaction_type": "SALE", "response_message": "APPROVAL", "status": "Confirmed" }, "metadata": { "correlation_id": "b059fdbd-0a28-4b6b-b41e-603b2532cc35", "timestamp": "2026-03-24T13:37:34.188432+00:00" } } The response includes a breakdown of both the base amount and the surcharge amount. References: Endpoint: Rectangle Health Pay (CP) - Surcharged Payment Initialization Rectangle Health Pay (CNP) - Sale with Surcharge Flowchart: RH Pay (CP) Sale RH Pay (CNP) Sale B. Void/Refund on Surcharged Transaction For void and refund on surcharged transactions, integrators must provide the net transaction amount only, excluding surcharge. The system automatically calculates and applies the applicable surcharge amount. Full Void/Refund For a full void or refund, the original net transaction amount, excluding surcharge fee, should be provided in the request. Exapmle : Original settled transaction: $20.60 Base amount: $20.00 Surcharge: $0.60 Request amount must be $20.00. The system automatically includes and processes the associated $0.60 surcharge. Partial Void/Refund on Surcharged Transaction Partial voids and refunds follow the same principle. When performing a partial void or refund: Only the partial net amount being voided or refunded, excluding surcharge fee, should be provided in the request. The system will: Calculate the prorated surcharge based on the provided net amount. Apply the prorated surcharge fee to the void/refund. Return the applicable breakdown in the response. Example : Original settled transaction: $20.60 Base: $20.00 Surcharge: $0.60 Partial void/refund of $10.00 (base): Request amount must be $10.00. System-calculated prorated surcharge: $0.30 Total void/refund amount processed: $10.30 The remaining balance is automatically calculated and returned in the response, including a breakdwon of base and surcharge amounts. Response Breakdown Behavior ( net_amount and fee_amount ) is explained in the next section. Notes Integrators must provide only the net transaction amount , excluding surcharge, for void and refund requests. Integrators should not calculate or include surcharge amount in the request. For partial void/refund requests, the system automatically calculates the prorated surcharge . The system automatically returns the remaining balance with a breakdown of base and surcharge. API Examples Base URL : https://services-sandbox.rectanglehealth.com (UAT) Endpoint : POST /api/v1/refund Example Request : JSON { "transaction_id": "{{transaction_id}}", "refund_amount": { "net_amount": "{{net_amount}}" }, "refund_reason": "OPTIONAL REFUND REASON" } Example Response: (Full Void) Full void processed on a $30.90 surcharged transaction: Net amount: $30.00 Surcharge/Fee amount: $0.90 Request amount: $30.00 Total amount processed by the system: $30.90 JSON { "data": { "device_serial_number": null, "merchant_account_id": "6374001", "merchant_name": "Rectangle", "last_four": "0043", "card_bin": "476173", "masked_pan": "476173******0043", "card_type": "VISA", "cvv_result": "M", "avs_result": "U", "account_holder_name": "Test Name", "entry_mode": "KEYED", "expiration_date": "1231", "settle_amount": 3090, "fee_amount": 90, "net_amount": 3000, "requested_amount": -3090, "customer_address_line1": "street", "customer_city": "city", "customer_state": "WA", "customer_zip": "12345", "payment_token": "2967534833764413", "card_identifier": "CREDIT", "auth_code": "518718", "result_code": "A", "result_message": "APPROVED", "transaction_id": "K09U2HQDE2", "invoice_number": "744_754", "sale_date_time": "20260327141838", "transaction_type": "SALE", "response_message": "APPROVAL", "status": "Voided", "is_partial_void": false }, "metadata": { "correlation_id": "e2af8bd9-2dba-49b6-ae98-3b11ee3db76b", "timestamp": "2026-03-27T18:19:14.262851+00:00" } } (Partial Void) Partial void of $10.00 net amount processed on a $30.90 surcharged transaction: Original net amount: $30.00 Original surcharge/fee amount: $0.90 Request amount: $10.00 System-calculated prorated surcharge: $0.30 Total void amount processed by the system: $10.30 Remaining transaction amount: $20.60, including $20.00 base and $0.60 surcharge JSON { "data": { "device_serial_number": null, "merchant_account_id": "6374001", "merchant_name": "Rectangle", "last_four": "0043", "card_bin": "476173", "masked_pan": "476173******0043", "card_type": "VISA", "cvv_result": "M", "avs_result": "U", "account_holder_name": "Test Name", "entry_mode": "KEYED", "expiration_date": "1231", "settle_amount": 2090, "fee_amount": 61, "net_amount": 2029, "requested_amount": -1000, "customer_address_line1": "street", "customer_city": "city", "customer_state": "WA", "customer_zip": "12345", "payment_token": "2967531423684498", "card_identifier": "CREDIT", "auth_code": "780095", "result_code": "A", "result_message": "APPROVED", "transaction_id": "K6IBT334AM", "invoice_number": "377_521", "sale_date_time": "20260327140620", "transaction_type": "SALE", "response_message": "APPROVAL", "status": "Confirmed", "is_partial_void": true }, "metadata": { "correlation_id": "1563a167-6791-4f5b-b69c-1b314f2d916f", "timestamp": "2026-03-27T18:11:40.996891+00:00" } } The response includes a breakdown of both the base amount and the surcharge amount. References: Endpoint: Rectangle Health Pay (CNP) - Void/Refund on Surcharged Transaction Rectangle Health Pay (CNP) - Partial Void/Refund on Surcharged Transaction Flowchart (upcoming) Response Breakdown Behavior ( net_amount and fee_amount ) To avoid ambiguity, the net_amount / netAmount (base amount) and fee_amount / feeAmount (surcharge) fields in the response represent different values depending on the transaction type and state (settled vs. unsettled) . 1. Partial Void - Unsettled Transaction For partial voids , the breakdown reflects the remaining balance that will be settled , not the voided amount. A void is performed on an unsettled transaction . The requested amount is canceled from the original transaction before settlement . The response returns the remaining amount that will be settled ( settled_amount ). Example: Original transaction: $30.90 (Base: $30.00, Surcharge: $0.90) Partial void request: $10.30 Remaining amount: $20.60 Response breakdown: net_amount : $20.00 fee_amount : $0.60 This represents the remaining settled amount , not the voided portion. 2. Partial Refund - Settled Transaction For partial refunds , the breakdown reflects the requested refund amount . Refunds apply to already settled transactions . A refund creates a new transaction . The response shows the breakdown of the refund amount being processed . Example : Original transaction: $30.90 (Base: $30.00, Surcharge: $0.90) Partial refund request: $10.30 Response breakdown: net_amount : $10.00 fee_amount : $0.30 This represents the refund transaction amount , which will be settled as a new transaction. 3. Full Void/ Full Refund For full voids and full refunds , the breakdown reflects the entire transaction amount being reversed . The full amount (base + surcharge) must be provided in the request. The response shows the complete breakdown of the reversed amount . Example : Original transaction: $30.90 Response breakdown : net_amount : $30.00 fee_amount : $0.90 This represents the full amount being voided or refunded . Summary Comparison Aspect Sale Void/Refund Default Behavior Surcharge is applied by default when enabled unless nonSurcharge = true . No default behavior. The amount being voided or refunded must be provided by the integrator. Surcharge Calculation Automatically calculated by the API based on the configured percentage. Automatically calculated by the API based on the net amount provided. For partial void/refund, the prorated surcharge is calculated by the API. Request Requirements No additional fields required. nonSurcharge is only provided when explicitly avoiding surcharge. The request amount (e.g., net_amount ) must include only the net transaction amount, excluding surcharge. Eligibility Check Performed by the API Performed by the API Surcharge in Response Returned in the response as fee_amount Returned in the response as fee_amount Support If you have any questions or concerns, please contact the Integration Team ( integration@rectanglehealth.com ). • [Flowchart](https://docs.rectanglehealth.com/rh_api/user-guide/flowchart.md): The Flowchart section provides a visual representation of key processes and decision pathways across various APIs. These diagrams help users understand how different components interact, the logic behind specific operations, and the conditions that influence workflow outcomes. By leveraging these flowcharts, developers and integrators can more easily model, analyze, and implement complex API sequences — improving clarity, accuracy, and overall integration efficiency. • [Card-Present (RH Pay)](https://docs.rectanglehealth.com/rh_api/user-guide/flowchart/surcharge/card-present-rh-pay.md): This flowchart outlines how users seamlessly process in-person payments with surcharge using physical card readers. Users can securely capture transaction details, authorize payments, and manage card-present interactions to facilitate efficient and reliable payment acceptance. • [Card-Not-Present (RH Pay)](https://docs.rectanglehealth.com/rh_api/user-guide/flowchart/surcharge/card-not-present-rh-pay.md): This flowchart illustrates how to process card-not-present transactions with surcharge securely and efficiently through RH Pay. It enables you to authorize, capture, and manage payments where the cardholder is not physically present, ensuring seamless handling of remote payments. • [Void/Refund](https://docs.rectanglehealth.com/rh_api/user-guide/flowchart/surcharge/void-refund.md): This flowchart outlines how users to reverse or refund previously authorized transactions, providing control over unsettled or settled payments. This functionality helps manage payment corrections and ensure accurate financial records by either voiding pending charges or issuing refunds for completed transactions. • [Rectangle Health Pay - Card Present](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-present.md): Overview The Rectangle Health Pay - Card Present section enables seamless processing of card-present transactions using supported PAX terminals. Users can securely authorize and capture payments directly at the ponit of sale, ensuring efficient and reliable card-present payment handling. Authentication Information To process card-present transactions, the terminal must be onboarded and configured in the Rectangle Health system with the corresponding gateway information. Each payment request must include the device serial number. The platform uses this value to identify the terminal device and determine the associated merchant account. Once the request is received, the gateway routes the transaction to the specified terminal, which then initiates the payment flow for customer interaction and processing. Terminal Information (Supported PAX Series) PAX A77 PAX A920 Max PAX A35 Support If you have any issues or questions, please reach out to Integration (integration@rectanglehealth.com). • [Payment Initialization](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-present/payment/payment-init.md): The following example shows how to initialize a card-present payment by specifying the transaction amount and device details. It enables you to start the payment process securely. Successful initialization returns approval confirmation along with a relevant transaction data. • [Surcharged Payment Initialization](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-present/payment/surcharged-payment-initialization.md): The following example shows how to initialize a surcharged payment by specifying the necessary details and surcharge parameters. It enables you to seamlessly apply additional fees to a transaction while creating a payment, ensuring accurate charge processing and reporting within your workflow. The surcharge will automatically be applied when the nonSurcharge field is set to false (if not provided, the default behavior is to apply the surcharge) based on the the percentage configured for the account during onboarding. Please refer to the feeAmount field to identify how much has been surcharged for the transaction. • [Custom Fields](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-present/custom-fields.md): The Custom Fields section provides information about custom fields supported by the API. Custom fields allow merchants to include organization-specific data in payment requests, enabling greater flexibility for transaction tracking, reconciliation, and reporting. Custom Field Character Limits The following limits apply when submitting custom fields: Payment Type Maximum Combined Length 5 fields 1,000 characters The combined length is calculated across all custom field names and values included in the request. Response and Reporting Availability Custom fields submitted in a sale request are returned in: Sale transaction responses Refund transaction responses Reporting API response for sale transactions Please note that refund transactions returned by the Reporting API do not include custom field data. To retrieve the custom fields associated with a refunded transaction, use the Reporting API to retrieve the original sale transaction. • [Sale with Custom Fields](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-present/custom-fields/sale-with-custom-fields.md): The following example demonstrates how to process a card payment sale request that includes custom fields. This enables enhanced tracking, reconciliation, and reporting by associating transactions with tailored information specific to your business needs. • [Rectangle Health Pay - Card Not Present](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present.md): Overview The Rectangle Health Pay - Card Not Present section enables secure processing of transactions where the card is not physically present, such as online or virtual payments. This API supports core transaction operations including sale, void/refund, and partial void/refund. It is designed to work with encrypted payment data, allowing merchants to securely submit card information while maintaining PCI compliance. Authentication Information Card-not-present transactions require API key-based authentication to authorize requests. Each request must include a valid API key in the request headers. This key identifies the calling application and ensures that only authorized clients can access the API. The merchant account is specified within the request to ensure the transaction is processed under the correct account. Encryption Requirements Sensitive payment data must be encrypted prior to submission using the provided client-side encryption method. This ensures that cardholder data is securely transmitted and not exposed within the merchant's environment. Encryption requirements apply only to endpoints that accept sensitive payment data, such as Sale endpoint. Support If you have any issues or questions, please reach out to Integration (integration@rectanglehealth.com). • [Payment Encryption](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/payment-encryption.md): Rectangle Health Payment Encryption provides an iframe-based method for securely collecting and encrypting payment information before submitting a transaction. Two versions of the Payment Encryption integration are available. ✔️ Payment Encryption v1 Use Payment Encryption v1 for integrations using the original Payment Encryption implementation. ✔️ Payment Encryption v2 Payment Encryption v2 enhances the security of the iframe integration by introducing a server-created, short-lived checkout session. The embedding page's origin is provided when the session is created over an authenticated server-side request rather than being passed in the browser URL. The checkout session authorizes the embedding origin and provides the payment iframe URL. Payment information is collected and encrypted inside the iframe, and the encrypted data is returned to the parent page for server-side transaction processing. • [Payment Encryption v1](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/payment-encryption/payment-encryption-v1.md): This script leverages client-side encryption of sensitive payment data before transmission to the server. It ensures that cardholder information is protected during transit by applying encryption algorithms within a secure browser-based environment. The embedded payment form supports custom styling via CSS, allowing integrators to align the user interface with their application's design. When applying custom styles, care should be taken to preserve usability, accessibility, and the integrity of required payment fields. Additionally, implementers should avoid modifying or interfering with the underlying payment logic and ensure that all interactions occur within the secure iframe context. Script Configuration Parameters The payment iframe supports optional query parameters that control the payment type and whether the amount field is displayed. Base Script URL HTML <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js"></script> <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js"></script> display_amount : Controls whether the payment amount field is shown in the iframe. Default Behavior : The current default integration behavior shows the amount field. This generates a card payment ifram with the amount field. Hide the Amount Field : To hide the amount field, use the base script URL with the parameter: HTML <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?display_amount=false"></script> <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?display_amount=false"></script> When display_amount=false, the amount attribute is not included in the generated payload section({ }). is_ach : Controls whether the iframe collects ACH information instead of card payment information. Default Value : The current default ingration value sets to false . When omitted, the iframe collects card payment informaiton. ACH Payment Frame : To collect ACH payment information (bank account number and routing number), set is_ach=true : HTML <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?is_ach=true"></script> <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?is_ach=true"></script> This generates an ACH payment iframe instead of the standard card payment iframe. Configuration Example Use Case Script URL Card payment with amount field https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js Card payment without amount field https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?display_amount=false ACH payment with amount field https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?is_ach=true ACH payment without amount field https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?is_ach=true&display_amount=false Full Document Example (card paymenet without amount field) HTML <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>CNP-Encryption-Example</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <h1>CNP Encryption Example</h1> <iframe id="payment-frame" srcdoc='<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?display_amount=false"></script> </body> </html>' allow="payment" width="400" height="275" sandbox="allow-scripts allow-forms allow-same-origin" referrerpolicy="no-referrer" ></iframe> <section id="output-section" aria-labelledby="output-heading"> <div id="result" aria-live="assertive"></div> </section> <script> const CIPHERPAY_ORIGIN = null; window.addEventListener("message", (event) => { // Origin check — required in production to prevent spoofed messages. if (CIPHERPAY_ORIGIN && event.origin !== CIPHERPAY_ORIGIN) return; const message = event.data; // We only handle the CipherPay standardized envelope. if (message.type !== "PAYMENT_RESULT") return; const resultDisplay = document.getElementById("result"); // Update the result banner with the appropriate style and text. if (resultDisplay) { resultDisplay.className = message.status; // applies "success", "failure", or "error" CSS class if (message.code === "ENCRYPTED_DATA" && message.data?.encrypted) { // Show a truncated preview so the customer sees something happened. // In production you'd likely redirect or show a confirmation instead. resultDisplay.textContent = message.data.encrypted; } else { resultDisplay.textContent = `${message.message} (${message.code})`; } } if (message.status === "success" && message.code === "ENCRYPTED_DATA") { console.log("Encrypted payload ready — send to your server:", message.data.encrypted); } if (message.status === "success" && message.code === "APPROVED") { const frame = document.getElementById("payment-frame"); if (frame) frame.style.display = "none"; } if (message.status === "failure") { } if (message.status === "error") { console.error("CipherPay error:", message.code, message.message); } }); </script> </body> </html> <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>CNP-Encryption-Example</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <h1>CNP Encryption Example</h1> <iframe id="payment-frame" srcdoc='<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <script src="https://api.qa.rectangle.health/cipherpay/api/v1/pay/rh-payment.js?display_amount=false"></script> </body> </html>' allow="payment" width="400" height="275" sandbox="allow-scripts allow-forms allow-same-origin" referrerpolicy="no-referrer" ></iframe> <section id="output-section" aria-labelledby="output-heading"> <div id="result" aria-live="assertive"></div> </section> <script> const CIPHERPAY_ORIGIN = null; window.addEventListener("message", (event) => { // Origin check — required in production to prevent spoofed messages. if (CIPHERPAY_ORIGIN && event.origin !== CIPHERPAY_ORIGIN) return; const message = event.data; // We only handle the CipherPay standardized envelope. if (message.type !== "PAYMENT_RESULT") return; const resultDisplay = document.getElementById("result"); // Update the result banner with the appropriate style and text. if (resultDisplay) { resultDisplay.className = message.status; // applies "success", "failure", or "error" CSS class if (message.code === "ENCRYPTED_DATA" && message.data?.encrypted) { // Show a truncated preview so the customer sees something happened. // In production you'd likely redirect or show a confirmation instead. resultDisplay.textContent = message.data.encrypted; } else { resultDisplay.textContent = `${message.message} (${message.code})`; } } if (message.status === "success" && message.code === "ENCRYPTED_DATA") { console.log("Encrypted payload ready — send to your server:", message.data.encrypted); } if (message.status === "success" && message.code === "APPROVED") { const frame = document.getElementById("payment-frame"); if (frame) frame.style.display = "none"; } if (message.status === "failure") { } if (message.status === "error") { console.error("CipherPay error:", message.code, message.message); } }); </script> </body> </html> Response Example JSON {"encrypted_card_data":{"kid":"d29775d4-fc38-425b-a38d-bf9a253a0a2c","ciphertext_b64":"M6OBgZ6svvbGi3nrB3r5ftG2ogWfGNaNcb8DbsnzeFZ19fha3oq7tfwr0zsISK8cU7nrEKTDVOrXYuRk9+dGYXOfil3XOCVHXzIsrxVnfQ5v08Fjd5sJD42AEGre7WzFTOKlkcEz7iwRzyYxgZiUhnQxasnIQYHco5kxpeaur/aqsHyJqdF6+oVHMw+HZewBu/F6cIeaLqUFvVoajVg4JW5SN3txUY9/0bpAfHIVZ2QPSZmq6Hm0/dmVuFfis3374Jxjpi6QH8p44tBIhV36s3wADZa9iS+jdPj3C+8SFJZoGIw7uVkeGB3ROyf/fIUUUhxLd4hQc8MG0G0xTcyz2g==","nonce":"NBOetRZbMh3LDfbMrNfCPwC1qJV5iUOT","issued_at":1776187237,"expires_at":1776187297}} • [Payment Encryption v2](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/payment-encryption/payment-encryption-v2.md): The CipherPay v2 payment frame allows you to build an iframe-based credit card or bank (ACH) collection form. Card and bank data are entered and encrypted inside the CipherPay iframe, so your page never touches raw cardholder or bank account data. The integration works in four steps: Authorize — Your server calls POST /api/v2/checkout-session , providing the origin of the page that will embed the iframe. The request includes your API key and returns a short-lived session and a frame_url . Collect — Your page embeds the CipherPay iframe and the customer enters their payment information. Encrypt — On submit, the iframe validates the input and encrypts it client-side. Hand off — The iframe posts the encrypted envelope back to your page using window.postMessage . Your page sends the envelope to your server, which calls the CipherPay charge endpoint. The parent page communicates with the iframe using two postMessage message types: configure-fields — controls which fields are rendered, their order, required fields, and labels. apply-styles — applies supported cosmetic design tokens. The iframe returns the result using PAYMENT_RESULT . Before You Start Endpoints Endpoint Purpose POST /api/v2/checkout-session Called by your server to create a checkout session and receive the frame_url . Requires x-api-key and must not be called from the browser. GET /api/v2/pay/rh-payment-frame The iframe HTML shell. The browser loads this URL directly using the checkout session. Do not proxy it through your server. GET /api/v2/pay/rh-payment.js The payment form script loaded by the iframe shell. You do not request it directly. POST /api/v1/pay Called by your server with the encrypted payment envelope to complete the charge. The iframe is v2; the Pay endpoint remains v1. API Base URLs Environment Base URL Demo https://api.demo.rectanglehealth/cipherpay Production https://api.rectanglehealth/cipherpay Your API Key Creating a checkout session requires an x-api-key header. This is the same API key used to authorize charges and refunds and must remain on your server. Do not include the API key in browser JavaScript. The iframe URL, postMessage configuration messages, and result message do not require the API key. Your Parent Origin You do not register your origins with Rectangle Health in v2. Instead, provide the origin of the page that will embed the iframe as parent_origin when creating the checkout session. parent_origin must exactly match the actual origin of the embedding page, including: scheme host port The iframe uses the parent_origin stored on the checkout session for its frame-ancestors policy and postMessage origin checks. Steps 1 Create a Checkout Session Create the checkout session from your server: POST /api/v2/checkout-session The browser must never call this endpoint because it requires your API key. Request CURL curl -X POST "https://api.demo.rectangle.health/cipherpay/api/v2/checkout-session" -H "x-api-key: <YOUR_API_KEY>" -H "Content-Type: application/json" -d '{ "parent_origin": "https://shop.example.com", "is_ach": false, "display_amount": true, "unstyled": false, "show_helper_text": true }' Request Body Field Type Default Description parent_origin string - Required. The origin of the page that will embed the iframe. is_ach boolean false true creates a session for the bank (ACH) form; otherwise the card form is used. display_amount boolean true false removes the amount field and drops amount from the encrypted payload. unstyled boolean false true renders the form without the CipherPay stylesheet. show_helper_text boolean or null null true displays helper text under fields that define one. parent_origin is the only required request field. Unknown request fields are rejected with HTTP 422 . Response JSON { "session_id": "<opaque, 43-character URL-safe token>", "expires_at": 1787251234, "frame_url": "https://api.demo.rectangle.health/cipherpay/api/v2/pay/rh-payment-frame?session=...&display_amount=true" } expires_at is a Unix timestamp in seconds. Sessions last 15 minutes and are reusable within that window. They are time-limited, not single-use. Create one session per checkout attempt rather than one session per page load. The response contains no cardholder data and the session does not bind an amount. 2 Embed the Payment Iframe The payment frame is loaded directly by the customer's browser. HTML <iframe id="payment-frame" src="" width="500" height="820" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" ></iframe> <iframe id="payment-frame" src="" width="500" height="820" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" ></iframe> Keep the following iframe attributes: HTML sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" allow-forms allows the customer to submit the form. Do not add allow-same-origin . The iframe is intentionally sandboxed without it, which gives the frame an opaque origin. There is also no allow="payment" attribute. 3 Configure the Payment Fields Send a configure-fields message when the iframe loads. The fields array determines both which fields are included and the order in which they appear. For a card payment example: JavaScript const CARD_FIELD_ORDER = [ "account_holder_name", "pan", "exp_month", "exp_year", "cvv", "account_holder_zip", "amount" ]; const CARD_REQUIRED_FIELDS = [ "pan", "exp_month", "exp_year", "cvv" ]; const CARD_LABEL_OVERRIDES = { pan: "Card Number", exp_month: "Expiration Month", exp_year: "Expiration Year", cvv: "Security Code", amount: "Amount ($)", account_holder_name: "Name", account_holder_zip: "Zipcode" }; Send the configuration using postMessage : JavaScript frame.contentWindow.postMessage( { type: "configure-fields", fields: CARD_FIELD_ORDER, required_fields: CARD_REQUIRED_FIELDS, label_overrides: CARD_LABEL_OVERRIDES }, "*" ); targetOrigin must be "*" because the sandboxed iframe has an opaque origin. The configuration message does not contain cardholder data, tokens, or other secrets. The iframe independently checks the sender's event.origin against the parent_origin associated with the checkout session. Card Fields Field ID Default Label Control Max Length pan Card Number text (numeric) 19 exp_month Exp Month text (numeric) 2 exp_year Exp Year text (numeric) 4 cvv CVV text (numeric) 4 amount Amount ($) text (numeric) - account_holder_name Account Holder Name text 100 account_holder_street Account Holder Street text 100 account_holder_city Account Holder City text 60 account_holder_state Account Holder State select (US states) - account_holder_zip Account Holder ZIP text 10 account_holder_country_code Account Holder Country Code text 2 account_holder_phone Account Holder Phone text 15 account_holder_email Account Holder Email text 20 Core Card Fields The following fields make up the core card payment fields: pan exp_month exp_year cvv The fields array must contain either all four core card fields or none of them. A partial core field set is rejected with: JSON { type: "PAYMENT_RESULT", status: "error", code: "INVALID_FIELD_CONFIG" } Required Fields Nothing is required by default. For a card payment, send: JavaScript required_fields: [ "pan", "exp_month", "exp_year", "cvv" ] required_fields currently applies only to the core payment fields. Adding account_holder_* fields or amount to required_fields does not make those fields required. If an account-holder value must be mandatory, enforce it on your page or server. 4 Style the Payment Form Because the iframe is sandboxed and cross-origin, the parent page's stylesheet cannot reach the payment form. Send an apply-styles message instead. The card payment example uses: JavaScript const FORM_STYLES = { fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif", borderRadius: "4px", bodyPadding: "20px", fontSize: "14px", color: "#1a1a1a", inputBackground: "#ffffff", inputBorder: "1px solid #ccc", inputPadding: "5px", inputWidth: "100%", inputMarginBottom: "5px", focusBorderColor: "#007bff", focusShadow: "0 0 0 2px rgba(0, 123, 255, 0.25)", labelFontWeight: "600", labelColor: "#333", buttonBackground: "#28a745", buttonHoverBackground: "#218838", buttonColor: "#ffffff", buttonBorder: "none", buttonFontSize: "16px", buttonFontWeight: "bold", buttonPadding: "12px 15px", buttonWidth: "100%" }; Send the styles to the iframe: JavaScript frame.contentWindow.postMessage( { type: "apply-styles", styles: FORM_STYLES }, "*" ); Only supported style tokens are applied. Unsupported tokens are ignored. 5 Send the Configuration When the Iframe Loads Send both apply-styles and configure-fields when the iframe loads. The card-only integrator example pushes the configuration twice: JavaScript frame.addEventListener("load", function () { pushFrameConfig(); window.setTimeout(pushFrameConfig, 0); }); The first configuration message can race with the iframe installing its message listener. The second message is sent on a zero-delay timeout. Both messages are idempotent, so sending the configuration twice is safe. 6 Handle the Payment Result The iframe sends one message type to the parent page: PAYMENT_RESULT The result has the following shape: JSON { type: "PAYMENT_RESULT", status: "success" | "failure" | "error", code: "ENCRYPTED_DATA" | "INVALID_PAN" | ..., message: "human-readable description", data: { encrypted: "<JSON string>" } } When the payment data has been successfully validated and encrypted: Plain text status: "success" code: "ENCRYPTED_DATA" status: "success" code: "ENCRYPTED_DATA" data.encrypted contains the encrypted payload. Because the sandboxed iframe has an opaque origin, messages from the iframe arrive with: event.origin === "null" The result listener must also verify: event.source === frame.contentWindow The source check verifies that the message came from the payment iframe. 7 Encrypted Payment Data data.encrypted is a JSON string. For a card payment, the parsed value has the following shape: JSON { "encrypted_card_data": { "kid": "...", "ciphertext_b64": "...", "nonce": "...", "issued_at": 1786126736, "expires_at": 1786127636 }, "amount": 1234 } amount is included only when the amount field was rendered and is returned in cents. The encrypted envelope is short-lived. Submit it promptly and do not cache it. Keep the encrypted data out of logs and analytics. Send the encrypted payload to your own server. Do not call the CipherPay charge endpoint directly from the browser. 8 Complete the Payment Your server takes the parsed encrypted object and adds the transaction information it owns before submitting it to: POST /api/v1/pay The iframe is v2, but the Pay endpoint remains v1. Your server adds: merchant_account_code — terminal number, 1–32 characters. inv_num — invoice reference, 3–24 characters using [a-zA-Z0-9_-] . account_holder — may contain name , street , city , state , zip , country_code , phone , and email . The request may also include custom_fields , meta_data , transaction_type , and, for card payments, non_surcharge or accept_partial_amount . Authenticate the Pay request using the x-api-key header. Do not call /api/v1/pay from the browser. Card Payment Integration Example The published integrator.html example is a stripped-down, card-only implementation intended to be copied into an integration. It takes an already-created session ID from the page query string. For the hosted example: integrator.html?session=<session_id>&env=qa session is the session_id returned when the checkout session is created. env selects the API base URL used to build the iframe URL and must match the environment where the session was created. These query parameters belong to the example page. In an integration, the API base is part of the application's configuration and the session comes from the integrator's server. integrator.html HTML <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Checkout (Integrator, Card)</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="favicon.ico"> <link rel="stylesheet" href="styles.css"> </head> <!-- INTEGRATOR EXAMPLE — CARD ONLY ============================== Minimal card checkout shell. Sessions are minted out of band and passed in on this page's own query string (see integrator.js): ?session=<session_id> required — id from POST /api/v2/checkout-session ?env=<name> optional — local|qa|demo|preproduction|production (default: local). Mint the session against the same environment; a qa session will not resolve on local's frame route. Example: integrator.html?session=abc&env=qa The iframe is asked to render a reordered card field subset via the configure-fields bridge: account_holder_name, pan, exp_month, exp_year, cvv, account_holder_zip, amount (full card core set present together; amount included) Implementation note: the iframe carries data-configure-fields="false" so the bundled script does NOT push the full default CARD_* list; the integrator section owns configure-fields. apply-styles is still on (attribute absent), so the form keeps the full v1-derived look from FORM_STYLES. --> <body class="integrator-page"> <h1>Integrator Example (card)</h1> <!-- No allow="payment": same posture as full.html. sandbox and referrerpolicy stay load-bearing (allow-forms is required for submit). --> <!-- Border removed via .integrator-page iframe in styles.css — not an inline style. nginx CSP for v2 is style-src 'self', so style="..." is ignored. --> <iframe id="payment-frame" src="" width="500" height="820" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" data-configure-fields="false" ></iframe> <!-- This page does not load app.js. integrator.js's PAYMENT_RESULT listener currently only calls alert() and does not write into #result; this element is present but presently unused. --> <section id="output-section" aria-labelledby="output-heading"> <div id="result" aria-live="assertive"></div> </section> <!-- Single bundle: shared parent helpers + integrator page script. --> <script defer src="integrator.js"></script> </body> </html> <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Checkout (Integrator, Card)</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="favicon.ico"> <link rel="stylesheet" href="styles.css"> </head> <!-- INTEGRATOR EXAMPLE — CARD ONLY ============================== Minimal card checkout shell. Sessions are minted out of band and passed in on this page's own query string (see integrator.js): ?session=<session_id> required — id from POST /api/v2/checkout-session ?env=<name> optional — local|qa|demo|preproduction|production (default: local). Mint the session against the same environment; a qa session will not resolve on local's frame route. Example: integrator.html?session=abc&env=qa The iframe is asked to render a reordered card field subset via the configure-fields bridge: account_holder_name, pan, exp_month, exp_year, cvv, account_holder_zip, amount (full card core set present together; amount included) Implementation note: the iframe carries data-configure-fields="false" so the bundled script does NOT push the full default CARD_* list; the integrator section owns configure-fields. apply-styles is still on (attribute absent), so the form keeps the full v1-derived look from FORM_STYLES. --> <body class="integrator-page"> <h1>Integrator Example (card)</h1> <!-- No allow="payment": same posture as full.html. sandbox and referrerpolicy stay load-bearing (allow-forms is required for submit). --> <!-- Border removed via .integrator-page iframe in styles.css — not an inline style. nginx CSP for v2 is style-src 'self', so style="..." is ignored. --> <iframe id="payment-frame" src="" width="500" height="820" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer" data-configure-fields="false" ></iframe> <!-- This page does not load app.js. integrator.js's PAYMENT_RESULT listener currently only calls alert() and does not write into #result; this element is present but presently unused. --> <section id="output-section" aria-labelledby="output-heading"> <div id="result" aria-live="assertive"></div> </section> <!-- Single bundle: shared parent helpers + integrator page script. --> <script defer src="integrator.js"></script> </body> </html> integrator.js Use the supplied integrator.js with the HTML above. The script: Reads session and env from the example page URL. Builds the iframe URL using the selected environment and session. Loads the card payment iframe with show_helper_text=true and display_amount=true . Sends apply-styles and configure-fields . Sends the configuration again on a zero-delay timeout after the iframe load event. Listens for PAYMENT_RESULT . Verifies both the iframe origin and event.source . Retrieves message.data.encrypted when the iframe returns ENCRYPTED_DATA . JavaScript /** * integrator.js — single-file parent script for integrator.html (card-only) * ======================================================================== * Owns env selection (?env=), frame src rebuild, apply-styles, configure-fields, * and PAYMENT_RESULT handling. No ACH / bank paths. */ // ── Environment selection ──────────────────────────────────────────────── // ** NOTE ** not needed in a production app as the target URL would be // part of the code, not chosen by the user. // // ?env= values: local | qa | demo | preproduction | production (default: local). // Mint the checkout session against the same environment. const ENV_API_BASES = { demo: "https://api.demo.rectangle.health/cipherpay", production: "https://api.rectangle.health/cipherpay", }; const DEFAULT_ENV = "local"; /** Environment from ?env= when valid, else "local". */ function getSelectedEnv() { const envFromQuery = new URLSearchParams(window.location.search).get("env"); if (envFromQuery && Object.prototype.hasOwnProperty.call(ENV_API_BASES, envFromQuery)) { return envFromQuery; } return DEFAULT_ENV; } function getSelectedEnvApiBase() { return ENV_API_BASES[getSelectedEnv()]; } /** Read a query parameter off THIS PAGE's own URL (never off a frame's). */ function getQueryParam(name) { return new URLSearchParams(window.location.search).get(name); } /** * Build GET /api/v2/pay/rh-payment-frame for an already-minted session. * Session must be minted against the same env as getSelectedEnv(). */ function buildFrameSrc(sessionId, extraParams) { const params = new URLSearchParams(Object.assign({ session: sessionId }, extraParams || {})); return getSelectedEnvApiBase() + "/api/v2/pay/rh-payment-frame?" + params.toString(); } const frame = document.getElementById("payment-frame"); // Styles pushed into the sandboxed frame via apply-styles (null-origin → "*"). const FORM_STYLES = { fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif", borderRadius: "4px", bodyPadding: "20px", fontSize: "14px", color: "#1a1a1a", inputBackground: "#ffffff", inputBorder: "1px solid #ccc", inputPadding: "5px", inputWidth: "100%", inputMarginBottom: "5px", focusBorderColor: "#007bff", focusShadow: "0 0 0 2px rgba(0, 123, 255, 0.25)", labelFontWeight: "600", labelColor: "#333", buttonBackground: "#28a745", buttonHoverBackground: "#218838", buttonColor: "#ffffff", buttonBorder: "none", buttonFontSize: "16px", buttonFontWeight: "bold", buttonPadding: "12px 15px", buttonWidth: "100%", }; // Card-only reduced field set. amount is optional at the frame layer. const CARD_FIELD_ORDER = [ "account_holder_name", "pan", "exp_month", "exp_year", "cvv", "account_holder_zip", "amount", ]; const CARD_REQUIRED_FIELDS = ["pan", "exp_month", "exp_year", "cvv"]; const CARD_LABEL_OVERRIDES = { pan: "Card Number", exp_month: "Expiration Month", exp_year: "Expiration Year", cvv: "Security Code", amount: "Amount ($)", account_holder_name: "Name", account_holder_zip: "Zipcode", }; /** * Push styles + field config into the frame after it loads. * targetOrigin must be "*" (sandbox without allow-same-origin → null origin). */ function pushFrameConfig() { if (!frame || !frame.contentWindow) { return; } frame.contentWindow.postMessage( { type: "apply-styles", styles: FORM_STYLES, }, "*" ); frame.contentWindow.postMessage( { type: "configure-fields", fields: CARD_FIELD_ORDER, required_fields: CARD_REQUIRED_FIELDS, label_overrides: CARD_LABEL_OVERRIDES, }, "*" ); } /** Rebuild the card frame src from ?session= + ?env=. */ function rebuildFrameSrc() { if (!frame) { return; } const sessionId = getQueryParam("session"); if (!sessionId) { frame.removeAttribute("src"); return; } // display_amount must stay true: display_amount=false drops amount in renderForm. frame.src = buildFrameSrc(sessionId, { show_helper_text: "true", display_amount: "true", }); } if (frame) { frame.addEventListener("load", function () { if (!frame.getAttribute("src")) { return; } // Listener is installed during frame script eval (before load). Post once // more on the next task in case the first message races the listener. pushFrameConfig(); window.setTimeout(pushFrameConfig, 0); }); } window.addEventListener("message", function (event) { // v2 frame is sandboxed without allow-same-origin → origin is always "null". // SECURITY: event.source check is the unforgeable guard; do not drop it. if (event.origin !== "null") return; if (!frame || event.source !== frame.contentWindow) return; const message = event.data; if (!message || message.type !== "PAYMENT_RESULT") return; const resultDisplay = document.getElementById("result"); if (resultDisplay) { if (message.code === "ENCRYPTED_DATA" && message.data && message.data.encrypted) { // Production would POST to your server. alert("The encrypted data could be sent to your server → POST /pay in place of this alert."); } else { alert("The encrypted data could be sent to your server → POST /pay in place of this alert."); } } if (message.status === "success" && message.code === "ENCRYPTED_DATA") { // INTEGRATION POINT: send message.data.encrypted to your server → POST /pay. } if (message.status === "success" && message.code === "APPROVED") { frame.style.display = "none"; // INTEGRATION POINT: redirect to confirmation. } if (message.status === "error") { console.error("CipherPay error:", message.code, message.message); } }); rebuildFrameSrc(); The integration point marked in integrator.js is where the encrypted data is sent to your own backend for processing. The iframe height in this example is fixed at 820 pixels for the seven-field form. The iframe does not send a resize message, so the parent page is responsible for sizing the iframe for the configured field count. ACH Reference Use this section as a reference when configuring the CipherPay iframe for bank (ACH) payments. Create an ACH Session Set is_ach to true when creating the checkout session: JSON { "parent_origin": "https://shop.example.com", "is_ach": true, "display_amount": true, "unstyled": false, "show_helper_text": true } When is_ach is true , the iframe renders the bank (ACH) form instead of the card form. The remaining iframe integration flow is the same: configure the fields using configure-fields , optionally apply supported styles using apply-styles , and handle the result through PAYMENT_RESULT . ACH Fields Field ID Default Label Control Max Length routing_number Routing Number text (numeric) 9 account_number Account Number text (numeric) 17 account_type Account Type radio group: Checking / Savings - amount Amount ($) text (numeric) - account_holder_name Account Holder Name text 100 account_holder_street Account Holder Street text 100 account_holder_city Account Holder City text 60 account_holder_state Account Holder State select (US states) - account_holder_zip Account Holder ZIP text 10 account_holder_country_code Account Holder Country Code text 2 account_holder_phone Account Holder Phone text 15 account_holder_email Account Holder Email text 20 account_type supports Checking and Savings and defaults to Checking. The same eight account_holder_* fields available for card payments are also available for ACH with the same labels and maximum lengths. Core ACH Fields The following fields make up the core ACH payment fields: routing_number account_number account_type If the fields array includes ACH payment fields, all three core fields must be present together. A partial core field set is rejected with: JSON { type: "PAYMENT_RESULT", status: "error", code: "INVALID_FIELD_CONFIG" } Required ACH Fields Nothing is required by default. For ACH payments, use: JSON required_fields: [ "routing_number", "account_number", "account_type" ] As with card payments, required_fields applies to the core payment fields. Adding account_holder_* fields or amount to required_fields does not make those fields required. Example ACH Field Configuration The fields array controls both which fields appear and their order. For example: JavaScript const ACH_FIELD_ORDER = [ "account_holder_name", "routing_number", "account_number", "account_type", "account_holder_zip", "amount" ]; const ACH_REQUIRED_FIELDS = [ "routing_number", "account_number", "account_type" ]; Send the configuration using the same configure-fields message used for card payments: JavaScript frame.contentWindow.postMessage( { type: "configure-fields", fields: ACH_FIELD_ORDER, required_fields: ACH_REQUIRED_FIELDS }, "*" ); Card field IDs sent to an ACH frame are ignored. Likewise, ACH field IDs sent to a card frame are ignored. ACH Encrypted Data When ACH data is successfully validated and encrypted, the iframe returns the same successful result code: Plain text status: "success" code: "ENCRYPTED_DATA" status: "success" code: "ENCRYPTED_DATA" For ACH, the encrypted payload uses: encrypted_bank_data instead of: encrypted_card_data The encrypted bank data uses the same envelope shape as encrypted card data. If amount is rendered, the encrypted payload also includes the amount in cents. When completing an ACH charge through /api/v1/pay , account_holder.name must be present and non-empty. A request containing encrypted_bank_data without account_holder.name is rejected with HTTP 400 . • [Sale](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/sale.md): The Sale section enables users to process payment transactions by capturing funds from a customer’s payment method. It facilitates secure and efficient handling of one-time purchases, allowing you to authorize and complete sales seamlessly within your application. • [Sale via Encrypted Card Data](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/sale/sale-via-encrypted-card-data.md): The following example demonstrates how to securely process payment transactions by submitting encrypted card data along with relevant transaction and account details. It supports capturing payment amounts and handling partial approvals for streamlined transaction processing and reconciliation. • [Sale via Encrypted Bank Data](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/sale/sale-via-encrypted-bank-data.md): The following example demonstrates how to securely process ACH payment transactions by submitting encrypted bank account data along with relevant transaction and account details. • [Sale via Payment Token](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/sale/sale-via-payment-token.md): The following example shows how to process a sale transaction securely by leveraging a previously generated payment_token , enabling payments without exposing sensitive card details. This request submits the transaction amount along with the associated merchant_account_code and uses the stored payment token to complete the payment without requiring card data. If surcharge is enabled for the merchant account and the stored payment method is eligible (e.g., credit card), the transaction will include a surcharge. To explicitly prevent a surcharge from being applied, set non_surcharge to true in the request. • [Sale via Card-on-File (CoF)](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/sale/sale-via-cof.md): The following example shows how to process a sale transaction by charging a previously stored payment method using cof_reference , enabling seamless payments wihtout requiring card details at the time of sale. This request submits the transaction amount along with the associated merchant_account_code and uses the stored payment token to complete the payment without requiring card data. If surcharge is enabled for the merchant account and the stored payment method is eligible (e.g., credit card), the transaction will include a surcharge. To explicitly prevent a surcharge from being applied, set non_surcharge to true in the request. Note : The merchant_account_code provided in the request must match the merchant account under which the Card-on-File (CoF) reference ( cof_reference ) was originally created. Otherwise, the request will return an error indicating that the CoF reference record was not found. • [Void/Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund.md): This section allows you to reverse completed transactions by voiding or refunding payments, either fully or partially. It helps manage payment adjustments effectively, ensuring accurate financial records and streamlined transaction management. • [Partial Void/Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/partial-void-refund.md): The following example shows how to initiate a partial void or refund request for completed transactions. Once the request is sent, the gateway checks the current settlement status of the transaction and proceeds accordingly - If the transaction is not settled, it will process a void; if the transaction is settled, it will process a refund. • [Full Void/Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/full-void-refund.md): The following example shows how to initiate a void or refund request for completed transactions. Once the request is sent, the gateway checks the current settlement status of the transaction and proceeds accordingly - If the transaction is not settled, it will process a void; if the transaction is settled, it will process a refund. • [Unreferenced Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/unreferenced-refund.md): The Unreferenced Refund section provides the information and examples needed to process refund transactions without referencing a previous payment. It supports refunds using multiple payment methods, including encrypted card data, encrypted bank data, payment tokens, and Card-on-File (CoF) references, while helping ensure secure and efficient refund processing. • [Unreferenced Refund via Encrypted Card Data](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/unreferenced-refund/unreferenced-refund-via-encrypted-card-data.md): The following example shows how to securely process an unreferenced refund by submitting encrypted card data along with the required transaction and account details. It supports issuing refunds without referencing a previous transaction while ensuring sensitive card information remains protected through encryption. • [Unreferenced Refund via Encrypted Bank Data](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/unreferenced-refund/unreferenced-refund-via-encrypted-bank-data.md): The following example shows how to securely process an unreferenced refund by submitting encrypted bank account data along with the required transaction and account details. It supports issuing refunds without referencing a previous transaction while ensuring sensitive bank account information remains protected through encryption. • [Unreferenced Refund via Payment Token](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/unreferenced-refund/unreferenced-refund-via-payment-token.md): The following example shows how to securely process an unreferenced refund using a payment token along with the required transaction and account details. It supports issuing refunds without referencing a previous transaction while eliminating the need to transmit sensitive payment credentials. • [Unreferenced Refund via Card-on-File (CoF)](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/void-refund/unreferenced-refund/unreferenced-refund-via-card-on-file-cof.md): The following example shows how to securely process an unreferenced refund using a Card-on-File (CoF) reference along with the required transaction and account details. It supports issuing refunds without referencing a previous transaction by utilizing securely stored payment credentials associated with the CoF reference. • [Surcharge](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/surcharge.md): This section outlines how to process transactions with surcharge applied using Rectangle Health Pay - Card Not Present (CNP). It covers how to submit surcharge-related details for sale transactions, as well as how to perform void, refund, and partial void/refund operations on surcharge transactions. Request Information When processing surcharge transactions, the request must include all relevant transaction details. Surcharge behavior is controlled using the ‘ non_surcharge ’ field. When ‘ non_surcharge ’ is set to ‘ false ’, a surcharge will be applied. If this field is not provided, the default behavior is to apply the surcharge. Condition Data Element Data Type Description Required non_surcharge Boolean If set to ‘false’ or not provided, a surcharge is applied. If set to ‘true’, no surcharge is applied. The surcharge amount is automatically calculated based on the percentage configured for the account during onboarding and is added to the base transaction amount to form the total transaction amount. Void/Refund on Surcharge Transactions When performing a void or refund on surcharge transaction, the amount provided in the request must include the surcharge amount. For example, consider a transaction with a total amount of $20.60, where the base (net) amount is $20.00 and the surcharge (fee) amount is $0.60: For a full void or refund, the amount specified in the request must be $20.60 (including the surcharge). For a partial void or refund of $10.00 from the base amount, the total amount to be provided in the request must be $10.30 (including the prorated surcharge). In this case: The base (net) amount voided/refunded will be $10.00 The surcharge (fee) amount voided/refunded will be $0.30 The API automatically calculates and returns the breakdown of base (net) and surcharge (fee) amounts in the response, including the remaining balance after the transaction. • [Sale](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/surcharge/sale.md): The following example demonstrates how to securely process surcharge payment transactions by submitting encrypted card data along with relevant transaction, surcharge, and account details. It supports capturing payment amounts, including applicable surcharge amounts, and handling partial approvals for streamlined transaction processing and reconciliation. The surcharge will automatically be applied when the nonSurcharge field is set to false (if not provided, the default behavior is to apply the surcharge) based on the the percentage configured for the account during onboarding. • [Full Void/Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/surcharge/full-void-refund.md): The following example shows how to initiate a void or refund request for completed surcharge transactions. Once the request is sent, the gateway checks the current settlement status of the surcharge transaction and proceeds accordingly - If the transaction is not settled, it will process a void; if the transaction is settled, it will process a refund. Provide the net transaction amount only (excluding any surcharge). The system will automatically include and process the associated surcharge. • [Partial Void/Refund](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/surcharge/partial-void-refund.md): The following example shows how to initiate a partial void or refund request for completed surcharge transactions. Once the request is sent, the gateway checks the current settlement status of the surcharge transaction and proceeds accordingly - If the transaction is not settled, it will process a void; if the transaction is settled, it will process a refund. Provide the net transaction amount only (excluding any surchaerge). The system will automatically calculate and apply the prorated surcharge. • [Custom Fields](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/custom-fields.md): The Custom Fields section provides information about custom fields supported by the API. Custom fields allow merchants to include organization-specific data in payment requests, enabling greater flexibility for transaction tracking, reconciliation, and reporting. Custom Field Character Limits The following limits apply when submitting custom fields: Payment Type Maximum Number of Fields Maximum Combined Length Card Payment 5 fields 1,000 characters ACH (Bank Transfer) 3 fields 225 characters The combined length is calculated across all custom field names and values included in the request. Response and Reporting Availability Custom fields submitted in a sale request are returned in: Sale transaction responses Refund transaction responses Reporting API response for sale transactions Please note that refund transactions returned by the Reporting API do not include custom field data. To retrieve the custom fields associated with a refunded transaction, use the Reporting API to retrieve the original sale transaction. • [Card Sale with Custom Fields](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/custom-fields/card-sale-with-custom-fields.md): The following example demonstrates how to process a card payment sale request that includes custom fields. Custom fields can be used to pass additional merchant-defined data with the transaction for tracking, reconciliation, and reporting purposes. • [ACH (Bank Transfer) Sale with Custom Fields](https://docs.rectanglehealth.com/rh_api/rectangle-health-pay-card-not-present/custom-fields/ach-sale-with-custom-fields.md): The following example demonstrates how to process an ACH (bank transfer) sale request that includes custom fields. Custom fields can be used to pass additional merchant-defined data with the transaction for tracking, reconciliation, and reporting purposes. • [Transaction Reporting API](https://docs.rectanglehealth.com/rh_api/transaction-reporting-api.md): Overview The Transaction Reporting API enables users to retrieve detailed transaction data for financial analysis, reporting, and reconciliation. It provides access to transaction records and related payment information, helping businesses monitor payment activity and generate accurate reports. This API supports retrieving transactions using the following methods: Invoice Number Transaction ID Merchant Account Code (MAC) Date Range and Merchant Account Code (MAC) Refer to the individual endpoint documentation for required parameters, supported filters, pagination options, and request/response examples. Authentication Information The Transaction Reporting API uses a simple API key-based authentication method to authorize requests. All API requests must include a valid API key in the request headers. This key uniquely identifies your account and ensures that only authorized clients can access the API. Support If you have any issues or questions, please reach out to Integration ( integration@rectanglehealth.com ). • [Get Transaction by Transaction ID](https://docs.rectanglehealth.com/rh_api/transaction-reporting-api/get-transaction-by-transaction-id.md): The following example shows how to retrieve comprehensive details of a specific transaction by providing its unique transaction ID. This endpoint allows users to access all relevant information related to the transaction, including merchant data, card details, amounts, status, and timestamps, enabling thorough transaction analysis and reconciliation. • [Get Transactions by Invoice Number](https://docs.rectanglehealth.com/rh_api/transaction-reporting-api/get-transactions-by-invoice-number.md): The following example shows how to retrieve complete details for a specific transaction by providing its corresponding invoice number. This endpoint enables users to access all relevant information associated with the transaction, including merchant data, card details, amounts, status, and timestamps, enabling thorough analysis and reconciliation based on the invoice reference. Note : ACH payment and refund transaction lookups are not supported via Invoice Number. To retrieve ACH payment transactions, please use the Get Transaction by Transaction ID endpoint. Refund transactions can be retrieved using either the Get Transaction by Transaction ID endpoint or the Get Transactions by Merchant Account Code (MAC) endpoint. • [Get Transactions by Merchant Account Code (MAC)](https://docs.rectanglehealth.com/rh_api/transaction-reporting-api/get-transactions-by-merchant-account-code.md): The following example shows how to retrieve transactions associated with a specific Merchant Account Code (MAC). This endpoint enables users to access transaction records for the specified merchant account, including merchant information, card details, transaction amounts, statuses, and timestamps, facilitating transaction review, reporting, and reconciliation. Pagination The transaction retrieval endpoints support pagination through the limit and page parameters. Limit Specifies the maximum number of transactions returned in a single API response. Defaults to 10 if not provided. Supported values range from 0 to 1000 . A maximum of 1000 transactions can be retrieved in a single API call. Page Specifies the page identifier used to retrieve a specific set of results. When additional transactions are available beyond the number returned by the current request, the response includes a nextPage value. To retrieve the next set of transactions, pass the returned nextPage value in the subsequent request. If no additional transactions are available, the nextPage field is returned as null . Note : ACH payment lookups are only supported via Transaction ID. To retrieve ACH payment transactions, please use Get Transaction by Transaction ID endpoint. • [Get Transactions by Date Range](https://docs.rectanglehealth.com/rh_api/transaction-reporting-api/get-transactions-by-date-range.md): The following example shows how to retrieve transactions associated with a specific Merchant Account Code (MAC) within a defined date range. This endpoint enables users to access transaction records for the specified merchant account, including merchant information, card details, transaction amounts, statuses, and timestamps, facilitating transaction review, reporting, and reconciliation over a selected period. Date Range Restrictions The maximum allowed date range is 31 days. The date_range_from field must be prior to the current date and cannot be set to today or a future date. The date_range_to field may be set to today's date but cannot be a future date. The date_range_to field is inclusive, meaning transactions from the specified end date are included in the response. Requests that exceed the 31-day limit or contain future dates will be rejected. Pagination The transaction retrieval endpoints support pagination through the limit and page parameters. Limit Specifies the maximum number of transactions returned in a single API response. Defaults to 10 if not provided. Supported values range from 0 to 1000 . A maximum of 1000 transactions can be retrieved in a single API call. Page Specifies the page identifier used to retrieve a specific set of results. When additional transactions are available beyond the number returned by the current request, the response includes a nextPage value. To retrieve the next set of transactions, pass the returned nextPage value in the subsequent request. If no additional transactions are available, the nextPage field is returned as null . Supported Query Parameters In additional to the date range parameters, the following optional query parameters are supported and may be used to further filter the results: Parameter Type Description merchant_account_code String Unique code identifying the merchant account for which transactions are being retrieved. merchant_id String Unique code identifying the merchant for which transactions are being retrieved. inv_num String The invoice number used as a query parameter to retrieve transactions associated with this specific invoice. Note : ACH payment lookups are only supported via Transaction ID. To retrieve ACH payment transactions, please use Get Transaction by Transaction ID endpoint. • [Card-on-File (CoF) API](https://docs.rectanglehealth.com/rh_api/card-on-file-cof-api.md): Overview The Card-on-File (CoF) API enables users to securely store and manage payment information for future use. It allows businesses to create reusable cof reference (a reference ID linking the payment token) that represent stored card data, eliminating the need to collect card details for each transaction. This API supports the following operations: Create a Card-on-File (CoF) for securely storing card/bank data Retrieve an existing Card-on-File (CoF) Delete a stored Card-on-File (CoF) Upon successful creation, the API returns a cof_reference and unique payment_token that can be used for further transactions. To retrieve or delete a Card-on-File (CoF), both the merchant_account_code and cof_reference are required. Clients should store these values securely, as they are necessary for managing stored payment data. Authentication Information The Card-on-File API uses API key-based authentication to authorize requests. All API requests must include a valid API key in the request headers. This key uniquely identifies your account and ensures that only authorized clients can access the API. Encryption Requirements The encrypted_card_data (for CC) / encrypted_bank_data (for ACH) field must be generated using the client-side encryption method described in the Payment Encryption . Encryption requirements apply only to endpoints that accept sensitive payment data, such as Create Card-on-File (CoF). Support If you have any issues or questions, please reach out to Integration ( integration@rectanglehealth.com ). • [Get Card-on-File](https://docs.rectanglehealth.com/rh_api/card-on-file-cof-api/get-card-on-file.md): The following example shows how to retrieve a stored Card-on-File including payment token using the merchant_account_code and cof_reference . Both parameters are required to locate the associated CoF record. • [Create Card-on-File (CC)](https://docs.rectanglehealth.com/rh_api/card-on-file-cof-api/create-card-on-file-cc.md): The following example shows how to create a Card-on-File (CoF) by submitting encrypted card data along with the associated merchant account. The encrypted_card_data field must be generated using the client-side encryption method described in the Payment Encryption . This request securely stores the card information and returns a reusable cof_reference and payment_token for future transactions. If cof_reference is not provided, it will be automatically generated by the system and returned in the resposne. • [Create Card-on-File (ACH)](https://docs.rectanglehealth.com/rh_api/card-on-file-cof-api/create-card-on-file-ach.md): The following example shows how to create a Card-on-File (CoF) by submitting encrypted bank data along with the associated merchant account. The encrypted_bank_data field must be generated using the client-side encryption method described in the Payment Encryption . This request securely stores the card information and returns a reusable cof_reference and payment_token for future transactions. If cof_reference is not provided, it will be automatically generated by the system and returned in the resposne. • [Delete Card-on-File](https://docs.rectanglehealth.com/rh_api/card-on-file-cof-api/delete-card-on-file.md): The following example shows how to delete a stored Card-on-File (CoF) using the merchant_account_code and cof_reference . Once deleted, both cof_reference and payment_token can no longer be used for future transactions. • [Product Release Notes](https://docs.rectanglehealth.com/rh_api/release-notes.md): Manage and retrieve detailed release notes for products within your RH API integration. This section enables you to access the latest updates, track changes across versions, and stay informed about new features or fixes to ensure seamless product maintenance and communication. • [API Release Notes](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes.md): Retrieve detailed information about the latest updates and changes to the RH API, including new features, improvements, and bug fixes. This section helps users stay informed about version history and plan integrations accordingly. • [v.3.2.1 - Released July 29, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v-3-2-1-released-july-29-2026.md): We're excited to announce the release of v3.2.1 , which enhances the Transaction Reporting API by introducing additional query parameters for more flexible transaction filtering. ✨ What's New 📍 Additional Query Parameters for Date Range Search The Get Transactions by Date Range endpoint now supports the following optional query parameters to further refine search results: Merchant Account Code (MAC) – Filter transactions for a specific Merchant Account Code. Merchant ID – Filter transactions for a specific merchant. Invoice Number – Filter transactions matching a specified invoice number. These parameters are optional and can be used individually or in combination with the required date range parameters to narrow the transaction results. 🛠 Support If you have any questions or need assistance, please contact our Integration team at integration@rectanglehealth.com . • [v.3.2.0 - Released July 24, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v-3-2-0-released-july-24-2026.md): We're excited to announce the release of v3.2.0 , introducing support for Unreferenced Refunds, expanded ACH payment capabilities, and enhanced transaction reporting. This release also includes Card-on-File (CoF) enhancements, additional payment method support, and new response fields to provide greater visibility into transaction and reporting data. ✨ What's New The following enhancements and new features have been added to the RH API to expand payment capabilities, improve reporting, and provide additional response data. 📍 Unreferenced Refund Support Added support for Unreferenced Refunds , allowing merchants to issue refund transactions without referencing a previous payment transaction. Supported payment methods include: Encrypted Card Data Encrypted Bank Account (ACH) Data Payment Token Card-on-File (CoF) Reference 📍 Card-on-File (CoF) API Enhancement - ACH Support The Card-on-File (CoF) API now supports storing ACH payment information in addition to card payment data. You can now create and manage Card-on-File records using encrypted bank account information for future ACH transactions. 📍 Payment Method Enhancement - ACH Support Support for ACH payment methods has been expanded across payment endpoints. The following ACH payment methods are now supported: ACH Payment Token ACH Card-on-File (CoF) Reference Example requests demonstrating ACH payment processing have also been added to the applicable payment endpoints, including: Sale via Payment Token Sale via Card-on-File (CoF) 📍 Reporting API Enhancement - CVV Verification Data The Reporting API response now includes the following fields to provide additional CVV verification details: CVVResponse CVVMessage These fields enable downstream applications to access richer CVV verification information for reporting and reconciliation purposes. 📍 Response Code Enhancements Additional response code fields have been introduced to provide greater visibility into processor responses. Transaction API Added response_code to transaction responses. Reporting API Added SourceResponseCode to reporting responses. These fields expose the processor response code to support troubleshooting, reporting, and downstream integrations. ✨ Learn More For implementation details, refer to the following documentation: Unreferenced Refund Card-on-File (CoF) ACH Support 🛠 Support If you have any questions or need assistance, please contact our Integration team at integration@rectanglehealth.com . • [v.3.1.1 - Released June 15, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v-3-1-1-released-june-15-2026.md): We're excited to announce the release of v3.1.1, which introduces new documentation resources, enhanced transaction reporting capabilities, and support for custom fields within payment transactions. ✨ New Features 📍 Gateway Reference User Guides A new Gateway References section has been added to the User Guide to provide additional insight into payment authorization, verification, and gateway processing responses. The following reference documents are now available: ✔ AVS/CVV Response Codes Provides detailed information about Address Verification Service (AVS) and Card Verification Value (CVV) response codes returned during transaction processing, helping users understand cardholder verification results. ✔ Bank (Issuer) Response Codes Provides descriptions of response codes returned by the card issuer, enabling users to better understand authorization outcomes and issuer-declined transactions. ✔ Gateway Response Codes Provides detailed information about gateway response codes returned in the result_code field of API responses, helping developers better understand transaction outcomes and troubleshoot processing issues. Benefits Improved troubleshooting and supportability Greater visibility into authorization and verification results Faster issue resolution through standardized response code references Enhanced understanding of transaction processing outcomes 📍 Reporting API enhancements The Reporting API has been expanded with new transaction retrieval capabilities. ✔ Get Transactions by Merchant Account Code (MAC) Transactions can now be retrieved using a Merchant Account Code (MAC), allowing users to query all transactions associated with a specific merchant account. ✔ Get Transactions by Date Range and Merchant Account Code (MAC) Users can now retrieve transactions for a specific Merchant Account Code (MAC) within a defined date range. Date Range Restrictions Maximum supported date range is 31 days date_range_from must be prior to the current date date_range_to may be today's date but cannot be a future date date_range_to is inclusive Additional functionality includes: Pagination support through limit and page parameters Configurable transaction retrieval limits up to 1,000 records per request nextPage response support for navigating large result sets Benefits Improved reporting flexibility Easier merchant-level reconciliation More efficient retrieval of historical transaction data Reduced need for individual transaction lookups For complete implementation details, request parameters, and response examples, refer to the updated API documentation. 📍 Custom Fields Support Custom Fields are now supported within payment transactions, enabling partners to associate additional business-specific information with transaction records. For detailed information about supported use cases, field requirements, restrictions, and implementation guidance, refer to the Custom Fields documentation available for both Card Present (CP) and Card Not Present (CNP) integrations: Card Present (CP) Custom Fields Card Not Present (CNP) Custom Fields Benefits Store application-specific metadata alongside transactions Improve reconciliation and reporting workflows Support custom business processes and integrations 🛠 Support If you have any questions or need assistance, please contact our Integration team at integration@rectanglehealth.com . • [v3.1.0 - Released April 17, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v-3-1-0-released-april-17-2026.md): This release introduces new APIs for transaction reporting and card-on-file functionality, enabling enhanced access to transaction data and secure storage of payment methods for future use. ✨ New Features ✔ Transaction Reporting API The Transaction Reporting API is now available, providing access to detailed transaction data for reporting and reconciliation purposes. Key capabilities include: Retrieve transactions by Invoice Number Retrieve transaction by Transaction ID Access detailed transaction data to support financial analysis and reporting ✔ Card-on-File (CoF) API The Card-on-File API is now available, enabling secure storage and management of payment data through tokenization. Key capabilities include: Create reusable payment token using encrypted card data Retrieve stored payment tokens Delete payment tokens when no longer needed Process transactions using stored payment tokens Additional highlights: Support secure handling of sensitive payment data via client-side encryption Enables reuse of stored payment methods without resubmitting card details 📝 Notes The Card-on-File API requires encrypted card data when creating a payment tokens. Refer to the Payment Encryption Guide for implementation details. API key-based authentication is required for all endpoints. 🛠 Support If you have any questions or need assistance, please contact our Integration team at integration@rectanglehealth.com . • [v3.0.0 - Released April 10, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v3-0-0-released-april-10-2026.md): We're excited to introduce Version 3, bringing major enhancements to our payment platform with improved reliability, security, and flexibility across both Card-Present (CP) and Card-Not-Present (CNP) solutions. ✨ What's New ✔ Rectangle Health Pay Card-Present (CP) Improvements We've enhanced our Card-Present solution to address timeout issues during terminal-based payment processing, and improved device identification by replacing system-generated UUIDs with device serial numbers, which provide a more stable and simplified identifier. Improved handling of terminal interactions Reduced transaction timeouts More reliable in-session payment flows More stable and simplified device identification using device serial numbers Card-Not-Present (CNP) Improvements We're introducing a new and improved payment encryption solution for Card-Not-Present transactions. What's improved: Tokens (encrypted data) no longer expire after a single use or 15-minute window Tokens (encrypted data) remain valid unless: Payment data changes Credentials or authorization changes Reduced need for repeated token generation Enhanced security and reliability Additional details are available here: Payment Encryption ✔ Surcharge Enhancements Surcharge support is now more flexible and fully managed by our system. Key updates: Supported for both CP and CNP transactions Automatically configured during onboarding System-managed surcharge calculation and application Option to opt out of surcharge per transaction (if enabled) Improved response transparency: Base Amount ( NetAmount / net_amount ) Surcharge Amount ( FeeAmount / fee_amount ) Additional details are available here: Surcharge Workflow 🛠 Support If you have any questions or need assistance, please contact our Integration team at integration@rectanglehealth.com . • [v2.0.3 - Released September 04, 2025](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v2-0-3-released-september-04-2025-copy.md): We're pleased to announce that surcharging is now supported for both Card-Present and Card-Not-Present transactions. Card-Present (PayGuardian Cloud API) Supported on PAX terminal devices only . The PAX terminal must be configured with surcharging enabled . No additional API parameters are required. Optionally, the terminal can be configured to prompt for surcharge confirmation before the transaction is processed. Only surchargable payment cards are supported. If a non-surchargable card (e.g., debit) is used, the transaction will either be declined, or proceed without surcharge (the surcharge amount will be automatically dropped). Card-Not-Present (Transction API / TokenPay.js) For CNP transactions, two additional parameters must be included: feeAmount - The surcharge amount to be applied. feeIsSurcharge - A Boolean (true / false) value, which indicates whether the feeAmount provided is for a Surcharge transaction. If true , and feeAmount is provided, the fee will be processed as a surcharge. If false or not provided, and feeAmount is provided, the fee will be processed as a convenience fee. API example available here: Credit Card Sale with Surcharge (Transaction API) TokenPay Credit Card Sale with Surcharge (TokenPay.js) 📩 Support If you have any questions or need assistance with PAX terminal configuration, please contact the Integration Team ( integration@rectanglehealth.com ). • [v2.0.1 - Released July 11, 2025](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v2-0-1-released-july-11-2025-copy.md): We're pleased to announce the release of expanded request field support on PAX terminal device through the PayGuardian Cloud (Card Present) integraiton. This enhancement allows integrators to send additional context such as custom data, notes, and vendor information with transactions, enabling more detailed reporting. ✅ What's New New Fields Support : support has been added for including the following fields in requests. customFields memo softwareVendor Compatible Devices : Available on all PAX termianls integrated with PayGuardian Cloud, running PGC v2.15.13 or later and BroadPOS BridgePay v1.02.05E_20250708 or later . 🔗 Documentation View full request details and examples here: PayGuardian Cloud Sale with Custom Fields • [v2.0.0 - Released April 17, 2025](https://docs.rectanglehealth.com/rh_api/release-notes/api-release-notes/v2-0-0-released-april-17-2025-copy-1.md): We're pleased to announce the relesae of Custom Field Support on Ingenico terminal devices through the PayGuardian Cloud (Card Present) integration. This enhancement allows integrators to send custom fields with credit sale and sale-auth tranactions, enabling the capture of business-specific data such as patient ID, account number, or internal tracking references. ✅ What's New Custom Fields Support : Send up to 5 custom fields in a request. Compatible Devices : Available on all Ingenico termianls integrated with PayGuardian Cloud, running the latest version 1.34. 🔗 Documentation View full request details and examples here: PayGuardian Cloud Sale with Custom Fields • [Authentication / Authorization Release Notes](https://docs.rectanglehealth.com/rh_api/release-notes/authentication-authorization-release-notes.md): Manage and review the latest updates and improvements related to authentication and authorization within the RH API. This section enables users to stay informed about changes that impact security protocols, access controls, and token management to ensure seamless integration and compliance. • [v3.0.0 - Released April 10, 2026](https://docs.rectanglehealth.com/rh_api/release-notes/authentication-authorization-release-notes/v3-0-0-released-april-10-2026.md): We've simplified and modernized our authentication model to improve security, usability, and integration consistency. ✨ What's changed 🔑 Unified Authentication with API Keys We have consolidated our previous authentication methods into a single, unified approach using API keys . Previous methods (deprecated): Basic Authentication (username/password) Key-based credentials (public/private key) New approach: A single API key is now used to authenticate API requests Note : API key authentication applies to all endpoints except Card-Present (CP) transactions. 📥 Authentication Header Requirement All API requests must include your API key in the request headers: JSON x-api-key: YOUR_API_KEY Requests without a valid API key will be rejected. Card-Present (CP) Authentication For Card-Present (CP) transactions, authentication is handled during terminal onboarding. API key is not required for CP requests Only the device serial number must be provided in the request payload The serial number is used to identify and authenticate the terminal device 💡 Benefits Simplified integration - one credential instead of multiple authentication methods Improved security - eliminates reliance on username/password authentication Consistent experience - unified authentication across all applicable endpoints Easier credential management - reduced complexity in key handling 🛠 Support If you have any questions or need assistance, please reach out to our Integration team ( integration@rectanglehealth.com ).