{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition","code-group"]},"type":"markdown"},"seo":{"title":"Sandbox Environment","description":"Complete documentation for integrating Cheqi's digital receipt platform","keywords":["cheqi","digital receipts","api","sdk","java","javascript"],"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"sandbox-environment","__idx":0},"children":["Sandbox Environment"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Cheqi sandbox is a fully functional test environment where you can build and test your integration without affecting production data. It mirrors the production API with pre-configured test customers so you can verify the complete receipt flow end-to-end."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"sandbox-details","__idx":1},"children":["Sandbox Details"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":""},"children":[]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":""},"children":[]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["API Base URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://sandbox.api.cheqi.io"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant Portal"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://sandbox.portal.cheqi.io"},"children":["sandbox.portal.cheqi.io"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Fully functional, mirrors production API"]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Sandbox vs Production"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sandbox environment is functionally identical to production. The only differences are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Client applications are ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["auto-approved"]}," (no review wait time)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Pre-configured ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["test customers"]}," with known card PARs and emails"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["merchant portal"]}," for managing companies, keys, and viewing receipts"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"getting-started","__idx":2},"children":["Getting Started"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-create-an-account","__idx":3},"children":["1. Create an Account"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Go to ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://sandbox.portal.cheqi.io"},"children":["sandbox.portal.cheqi.io"]}," and register with your email address. You'll receive a verification code to complete sign-up."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-register-a-company","__idx":4},"children":["2. Register a Company"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once logged in, create a company from the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dashboard"]}," (or click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Add Company"]},"). This registers your merchant identity in the sandbox."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-get-your-api-credentials","__idx":5},"children":["3. Get Your API Credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From the Dashboard, generate an ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["API Key"]}," for direct API access."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Include the key as a Bearer token in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header for all API calls:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl https://sandbox.api.cheqi.io/recipient/resolve \\\n  -H \"Authorization: Bearer sk_your_sandbox_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{...}'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Alternatively, create a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Client Application"]}," for OAuth2 integrations. Client applications are auto-approved in the sandbox, so you can start testing immediately."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-generate-and-upload-a-public-key","__idx":6},"children":["4. Generate and Upload a Public Key"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cheqi uses hybrid encryption (AES-256-GCM + RSA-OAEP with SHA-256). Upload a public key when you need to receive encrypted content from Cheqi. Keep the matching private key in your own infrastructure and use it to decrypt the wrapped AES key in each envelope — Cheqi never needs your private key."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You need a registered public key when you want to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Receive encrypted receipt copies"]}," — fetch issued receipts through the API or process receipt webhooks for your own company or client application."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Receive and process customer returns"]}," — return requests are encrypted to your public key (your ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["issuer key"]},") and you decrypt them with the matching private key. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Without a registered key, customers cannot send you returns and you cannot decrypt them."]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you only submit receipts for delivery to customer apps and do not handle returns, a public key is optional. Without one, Cheqi simply skips your company or client application as an encrypted downstream recipient; customer-app delivery still works."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"generate-an-rsa-key-pair","__idx":7},"children":["Generate an RSA Key Pair"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"# Generate a 2048-bit RSA private key\nopenssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem\n\n# Extract the public key\nopenssl rsa -in private_key.pem -pubout -out public_key.pem\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This creates:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["private_key.pem"]},": your PKCS#8 RSA private key (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-----BEGIN PRIVATE KEY-----"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_key.pem"]},": the X.509 SubjectPublicKeyInfo public key to upload to Cheqi (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-----BEGIN PUBLIC KEY-----"]},")"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Upload only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_key.pem"]},". Never upload ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["private_key.pem"]},"."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Keep Your Private Key Safe"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Store ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["private_key.pem"]}," securely — you'll need it to decrypt receipt copies sent to your application. Never share it or commit it to version control."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"upload-via-the-merchant-portal","__idx":8},"children":["Upload via the Merchant Portal"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Go to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dashboard"]}," on ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://sandbox.portal.cheqi.io"},"children":["sandbox.portal.cheqi.io"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Find your client application"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Paste the contents of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_key.pem"]},", or select the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_key.pem"]}," file"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Upload Key"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The portal reads the public key PEM content, validates that it is a public key, and encodes it before sending it to the API. Uploading ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_key.pem"]}," is equivalent to pasting the file contents. The portal rejects private-key files."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"upload-via-api","__idx":9},"children":["Upload via API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can also upload the public key programmatically. The API expects the PEM content to be ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Base64-encoded"]}," (to avoid newline issues in JSON):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"# Base64-encode the PEM file. This works on macOS and Linux.\nPUBLIC_KEY_B64=$(openssl base64 -A -in public_key.pem)\n\n# Upload to your client application\ncurl -X POST https://sandbox.api.cheqi.io/client-application/{clientApplicationId}/public-key \\\n  -H \"Authorization: Bearer YOUR_COMPANY_API_KEY_OR_ADMIN_USER_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\n    \\\"publicKey\\\": \\\"$PUBLIC_KEY_B64\\\",\n    \\\"keyAlgorithm\\\": \\\"RSA_2048\\\"\n  }\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The backend decodes the Base64-encoded PEM, strips the PEM headers and whitespace, validates the key, and stores the normalized public key material. If you later retrieve the key through the API, the returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["publicKey"]}," is the normalized key material, not the original PEM file."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"company-keys-api-key-integrations","__idx":10},"children":["Company keys (API-key integrations)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you integrate with a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["company API key"]}," rather than a client application, upload the company's public key instead. This is the key used as your ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["issuer key"]}," when you receive customer returns issued under your company:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"PUBLIC_KEY_B64=$(openssl base64 -A -in public_key.pem)\n\ncurl -X POST https://sandbox.api.cheqi.io/company/public-key \\\n  -H \"Authorization: Bearer YOUR_COMPANY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"{\n    \\\"publicKey\\\": \\\"$PUBLIC_KEY_B64\\\",\n    \\\"keyAlgorithm\\\": \\\"RSA_2048\\\"\n  }\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Supported key algorithms:"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Algorithm"},"children":["Algorithm"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RSA_2048"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["RSA 2048-bit with RSA-OAEP (SHA-256)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RSA_4096"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["RSA 4096-bit with RSA-OAEP (SHA-256)"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"5-submit-a-receipt","__idx":11},"children":["5. Submit a Receipt"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Choose your integration method:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"sdk-recommended","__idx":12},"children":["SDK (Recommended)"]},{"$$mdtype":"Tag","name":"CodeGroup","attributes":{"mode":"tabs"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","data-title":"Java","header":{"title":"Java","controls":{"copy":{}}},"source":"CheqiSDK sdk = CheqiSDK.builder()\n    .apiEndpoint(Environment.SANDBOX)\n    .apiKey(\"sk_your_sandbox_api_key\")\n    .build();\n\nIdentificationDetails id = new IdentificationDetails()\n    .paymentType(PaymentType.CARD_PAYMENT)\n    .cardDetails(new CardDetails()\n        .paymentAccountReference(\"SANDBOX-PAR-001\")\n        .cardProvider(CardDetails.CardProviderEnum.VISA));\n\nReceiptPayload receipt = ReceiptPayload.builder()\n    .documentNumber(\"INV-001\")\n    .issueDate(OffsetDateTime.now())\n    .currency(\"EUR\")\n    .totalAmount(new BigDecimal(\"12.10\"))\n    .totalTaxAmount(new BigDecimal(\"2.10\"))\n    .totalBeforeTax(new BigDecimal(\"10.00\"))\n    .receiptSubtotal(new BigDecimal(\"10.00\"))\n    .products(List.of(\n        Product.builder()\n            .name(\"Cappuccino\")\n            .identifier(\"SKU-CAPPUCCINO-001\")\n            .quantity(1.0)\n            .baseQuantity(1.0)\n            .unitCode(UnitCode.C62)\n            .unitPrice(new BigDecimal(\"10.00\"))\n            .subtotal(new BigDecimal(\"10.00\"))\n            .total(new BigDecimal(\"12.10\"))\n            .addTax(21.0, \"VAT\", \"10.00\", \"2.10\")\n            .build()\n    ))\n    .addTax(Tax.builder()\n        .rate(21.0)\n        .type(\"VAT\")\n        .taxableAmount(\"10.00\")\n        .amount(\"2.10\")\n        .label(\"VAT 21%\")\n        .build())\n    .taxesApplied(true)\n    .build();\n\nReceiptResult result = sdk.getReceiptService()\n    .issueReceipt(id, receipt);\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","data-title":"JavaScript","header":{"title":"JavaScript","controls":{"copy":{}}},"source":"import {\n  CheqiSDK,\n  Environment,\n  PaymentType,\n  UnitCode,\n  createReceiptPayload,\n  type IdentificationDetails,\n} from \"@cheqi/sdk\";\n\nconst sdk = new CheqiSDK({\n  apiEndpoint: Environment.SANDBOX,\n  apiKey: \"sk_your_sandbox_api_key\",\n});\n\nconst id = {\n  paymentType: PaymentType.CARD_PAYMENT,\n  cardDetails: {\n    paymentAccountReference: \"SANDBOX-PAR-001\",\n    cardProvider: \"VISA\",\n  },\n} satisfies IdentificationDetails;\n\nconst receipt = createReceiptPayload({\n  documentNumber: \"INV-001\",\n  issueDate: new Date(),\n  currency: \"EUR\",\n  totalAmount: \"12.10\",\n  totalTaxAmount: \"2.10\",\n  totalBeforeTax: \"10.00\",\n  receiptSubtotal: \"10.00\",\n  taxesApplied: true,\n  products: [{\n    name: \"Cappuccino\",\n    identifier: \"SKU-CAPPUCCINO-001\",\n    quantity: 1,\n    baseQuantity: 1,\n    unitCode: UnitCode.C62,\n    unitPrice: \"10.00\",\n    subtotal: \"10.00\",\n    total: \"12.10\",\n    taxes: [{ rate: 21, type: \"VAT\", taxableAmount: \"10.00\", amount: \"2.10\" }],\n  }],\n  taxes: [{\n    rate: 21,\n    type: \"VAT\",\n    taxableAmount: \"10.00\",\n    amount: \"2.10\",\n    label: \"VAT 21%\",\n  }],\n});\n\nconst result = await sdk.receiptService.issueReceipt(id, receipt);\n","lang":"javascript"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"rest-api","__idx":13},"children":["REST API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For manual integration, follow these steps:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Resolve recipient:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST https://sandbox.api.cheqi.io/recipient/resolve\nAuthorization: Bearer sk_your_api_key\nContent-Type: application/json\n\n{\n  \"cardDetails\": {\n    \"paymentAccountReference\": \"SANDBOX-PAR-001\",\n    \"cardProvider\": \"VISA\"\n  }\n}\n","lang":"bash"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Build the definitive receipt payload locally."]}," Do not send its plaintext"," ","contents to Cheqi."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Encrypt"]}," the same payload independently for every returned owner device"," ","(AES-256-GCM + RSA-OAEP, with a fresh AES key per device)."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Submit"]}," the complete per-device encrypted set:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST https://sandbox.api.cheqi.io/receipt/encrypted\n","lang":"bash"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"6-verify-delivery","__idx":14},"children":["6. Verify Delivery"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Go to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Receipts"]}," tab in the merchant portal to see your submitted receipt."," ","Click on it to view delivery status and, when available, the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["decrypted"," ","content"]},". To see decrypted content in the portal, issue the receipt against one"," ","of the sandbox test customer identifiers shown in the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Test Customers"]}," section"," ","of the portal. This proves the full end-to-end flow works: customer matching,"," ","per-device encryption, on-device generation, queuing, and decryption."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"decrypted-receipt-preview","__idx":15},"children":["Decrypted Receipt Preview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sandbox merchant portal can show decrypted receipt content only for receipts delivered to Cheqi's pre-configured sandbox test customers. Use one of the test customer identifiers shown in the portal, such as a test PAR or email address, when resolving the recipient for the receipt."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is a sandbox-only testing feature. The sandbox stores a private key for each seeded test customer, so when a receipt is delivered to one of those test-customer devices, the portal can decrypt that device copy and show:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the decrypted generation input and generated receipt"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["recipient delivery status for the issued receipt"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The portal does not decrypt arbitrary receipts. A receipt may have multiple encrypted copies, for example one for a customer device, one for a company, and one for a client application. The sandbox preview specifically looks for the copy encrypted to a sandbox test customer because that is the only customer-device private key Cheqi has in the sandbox."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sandbox test customers are shared fixtures across the sandbox environment; they are not created separately for each merchant company. The receipt preview is still scoped to your company: the portal only lists and decrypts receipts that your company issued. Another sandbox company cannot open your receipts just because it can see the same test customer identifiers."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Production Privacy"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This decrypted preview does not exist in production. In production, Cheqi does not store customer private keys and cannot read end-user receipt contents. Receipt payloads are decrypted by the receiving app, device, or client application that owns the matching private key."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the portal shows that decrypted preview is unavailable, the receipt was not delivered to a sandbox test customer. Use one of the PARs or emails from the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Test Customers"]}," section when you want to verify decrypted content in the portal."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"test-customers","__idx":16},"children":["Test Customers"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sandbox has pre-configured test customers with known card PARs and emails. These test customers are shared across sandbox merchants. Go to the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Test Customers"]}," section in the merchant portal to see the available identifiers you can use when resolving recipients. Receipts issued against these identifiers can be opened in the portal with decrypted receipt content, but only by the company that issued the receipt."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use these test PARs in your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["IdentificationDetails"]}," to simulate real customer matching:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"IdentificationDetails customer = new IdentificationDetails()\n    .paymentType(PaymentType.CARD_PAYMENT)\n    .cardDetails(new CardDetails()\n        .paymentAccountReference(\"SANDBOX-PAR-001\")  // Test customer PAR\n        .cardProvider(CardDetails.CardProviderEnum.VISA));\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"pairing-codes","__idx":17},"children":["Pairing Codes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In production, customers can generate a temporary ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["pairing code"]}," in the Cheqi app to identify themselves at checkout. This is especially useful for cash payments, gift cards, or any scenario where card data isn't available."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The customer shows an 8-digit code (or QR code) to the merchant, who includes it when submitting the receipt:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"IdentificationDetails customer = new IdentificationDetails()\n    .paymentType(PaymentType.CARD_PAYMENT)\n    .pairingCode(\"84739201\");  // 8-digit code from customer's app\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pairing codes are valid for ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["5 minutes"]}," and can only be used once. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/receipts/recipient-resolution#pairing-code-example"},"children":["Recipient Resolution"]}," for full details."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"sdk-configuration-for-sandbox","__idx":18},"children":["SDK Configuration for Sandbox"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Point your SDK to the sandbox API:"]},{"$$mdtype":"Tag","name":"CodeGroup","attributes":{"mode":"tabs"},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","data-title":"Java","header":{"title":"Java","controls":{"copy":{}}},"source":"CheqiSDK sdk = CheqiSDK.builder()\n    .apiEndpoint(Environment.SANDBOX)\n    .apiKey(System.getenv(\"CHEQI_SANDBOX_API_KEY\"))\n    .build();\n","lang":"java"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","data-title":"JavaScript","header":{"title":"JavaScript","controls":{"copy":{}}},"source":"import { CheqiSDK, Environment } from \"@cheqi/sdk\";\n\nconst sdk = new CheqiSDK({\n  apiEndpoint: Environment.SANDBOX,\n  apiKey: process.env.CHEQI_SANDBOX_API_KEY,\n});\n","lang":"javascript"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"company-management","__idx":19},"children":["Company Management"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can register multiple companies to test different merchant setups. Use the company switcher in the navigation bar to switch between them. Companies can be deactivated from the Dashboard when no longer needed — all API keys will be revoked but receipt data is retained for compliance."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"next-steps","__idx":20},"children":["Next Steps"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/receipts/overview"},"children":["Receipt Flow Overview"]}]}," - Understand the complete receipt delivery pipeline"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/authentication/overview"},"children":["Authentication"]}]}," - API Keys vs OAuth 2.0"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/sdk/java"},"children":["Java SDK"]}]}," - Full Java SDK documentation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/sdk/javascript"},"children":["JavaScript SDK"]}]}," - Full JavaScript and TypeScript SDK documentation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/cli/overview"},"children":["Cheqi CLI"]}]}," - Command-line receipt workflows"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/sdk/overview"},"children":["SDK & CLI Availability"]}]}," - Review supported integration tooling"]}]}]},"headings":[{"value":"Sandbox Environment","id":"sandbox-environment","depth":1},{"value":"Sandbox Details","id":"sandbox-details","depth":2},{"value":"Getting Started","id":"getting-started","depth":2},{"value":"1. Create an Account","id":"1-create-an-account","depth":3},{"value":"2. Register a Company","id":"2-register-a-company","depth":3},{"value":"3. Get Your API Credentials","id":"3-get-your-api-credentials","depth":3},{"value":"4. Generate and Upload a Public Key","id":"4-generate-and-upload-a-public-key","depth":3},{"value":"Generate an RSA Key Pair","id":"generate-an-rsa-key-pair","depth":4},{"value":"Upload via the Merchant Portal","id":"upload-via-the-merchant-portal","depth":4},{"value":"Upload via API","id":"upload-via-api","depth":4},{"value":"Company keys (API-key integrations)","id":"company-keys-api-key-integrations","depth":4},{"value":"5. Submit a Receipt","id":"5-submit-a-receipt","depth":3},{"value":"SDK (Recommended)","id":"sdk-recommended","depth":4},{"value":"REST API","id":"rest-api","depth":4},{"value":"6. Verify Delivery","id":"6-verify-delivery","depth":3},{"value":"Decrypted Receipt Preview","id":"decrypted-receipt-preview","depth":2},{"value":"Test Customers","id":"test-customers","depth":2},{"value":"Pairing Codes","id":"pairing-codes","depth":2},{"value":"SDK Configuration for Sandbox","id":"sdk-configuration-for-sandbox","depth":2},{"value":"Company Management","id":"company-management","depth":2},{"value":"Next Steps","id":"next-steps","depth":2}],"frontmatter":{"title":"Sandbox Environment","description":"Test your Cheqi integration end-to-end in a safe sandbox environment","seo":{"title":"Sandbox Environment"}},"lastModified":"2026-08-11T23:21:19.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/sandbox/getting-started","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}