엔드 투 엔드 프로젝트를 주문하면 빠른 테스트 또는 샌드박스 환경을 사용할 때 샌드박스 결제 모드를 구성할 수 있습니다. 데이터 피드를 테스트하는 동안 샌드박스 결제 모드와 프로덕션 결제 모드 간에 전환할 수 있습니다. 카드에 청구하지 않고 주문 엔드 투 엔드 프로젝트의 결제를 테스트하려면 결제 모드로 샌드박스를 사용하세요. 프로덕션 환경에서는 샌드박스 결제 모드를 지원하지 않습니다.
구성
샌드박스 환경에서 샌드박스 결제 모드를 사용 설정하려면 다음 단계를 따르세요.
- 작업 센터에서 구성 > 기능으로 이동합니다.
- 계정 기능 카드에서 결제 모드 라디오 버튼을 찾습니다.
- 샌드박스 옵션을 선택하고 변경사항 저장을 클릭합니다.
빠른 테스트 환경에서 샌드박스 결제 모드를 사용 설정하려면 다음 단계를 따르세요.
- Actions Center에서 피드 > 빠른 테스트로 이동합니다.
- GPay에 샌드박스 사용 라디오 버튼을 선택합니다.
샌드박스 결제 모드가 선택된 경우:
- 엔드 투 엔드 주문은 Google Pay가 실제 카드 세부정보 대신 테스트 카드 데이터가 포함된 수단 토큰을 반환하도록 구성합니다.
isInSandbox
필드는 CheckoutRequestMessage 및 SubmitOrderRequestMessage에서true
로 설정됩니다.
환경, 결제 모드, isInSandbox의 다양한 조합은 다음과 같습니다.
환경 | 결제 모드 | isInSandbox |
---|---|---|
빠른 테스트 | 샌드박스 | true |
빠른 테스트 | 프로덕션 | 거짓 |
샌드박스 | 샌드박스 | true |
샌드박스 | 프로덕션 | 거짓 |
프로덕션 | 프로덕션 | 거짓 |
결제 응답 메시지
음식 주문 웹 서비스에서 전송한 CheckoutResponseMessage
에는 PaymentOptions
가 포함되어 있습니다. 결제를 설정할 때 예시 결제 게이트웨이를 사용하여 자리표시자 결제 옵션을 제공합니다.
- 웹 서비스에서 전송하는
CheckoutResponseMessage
를 적절한 토큰화 구성으로 업데이트해야 합니다.
결제 옵션 예시
다음은 샌드박스 키를 사용하는 다양한 결제 게이트웨이의 CheckoutResponseMessage
에 있는 JSON PaymentOptions
객체의 예입니다.
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"braintree\",\"braintree:apiVersion\":\"v1\",\"braintree:sdkVersion\":\"1.4.0\",\"braintree:merchantId\":\"YOUR_MERCHANT_ID\",\"braintree:clientKey\":\"YOUR_BRAINTREE_SANDVOX_OR_PRODUCTION_KEY\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"stripe\",\"stripe:version\":\"2018-10-31\",\"stripe:publishableKey\":\"YOUR_PRODUCTION_OR_SANDBOX_STRIPE_KEY\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
"paymentOptions": { "googleProvidedOptions": { "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"stripev2\",\"gatewayMerchantId\":\"YOUR_PRODUCTION_OR_SANDBOX_STRIPE_KEY\"}}}],\"transactionInfo\":{\"currencyCode\":\"USD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"31.85\"}} " } }
샌드박스 거래 신고
샌드박스 결제 모드가 사용 설정되면 isInSandbox
필드가 요청에 포함되고 웹 서비스 엔드포인트 (CheckoutRequestMessage
및 SubmitOrderRequestMessage
)에 수신되는 요청의 경우 true
로 설정됩니다. isInSandbox
필드가 true
로 설정된 경우 다음을 실행합니다.
- 결제 게이트웨이의 토큰화 구성에서 프로덕션 키 대신 샌드박스 키를 사용합니다. 대부분의 결제 처리업체는 샌드박스와 프로덕션 모두에 API 키를 제공합니다.
- 웹 서비스 제공업체(일반적으로 음식점)와의 통신을 트리거하지 마세요. 웹 서비스 제공업체는 샌드박스 거래에 관해 알릴 필요가 없습니다.
거래 샌드박스가 사용 설정되어 있더라도 테스트 신용카드는 지원되지 않습니다. 거래 시 실제 신용카드를 사용해야 합니다. 그러나 샌드박스 계측 토큰에는 청구되지 않는 테스트 카드 세부정보가 포함되어 있습니다.
결제 처리
고객이 주문을 제출하면 주문 엔드 투 엔드에서 SubmitOrderRequestMessage를 웹 서비스 엔드포인트로 전송합니다. Google Pay 토큰은 SubmitOrderRequestMessage
instrumentToken 필드에 base64로 인코딩된 문자열로 포함됩니다. 고객의 결제를 처리하려면 결제 게이트웨이에 따라 다음 중 하나를 실행합니다.
결제 게이트웨이 | |
---|---|
Stripe 또는 Braintree | base64로 인코딩된 토큰 문자열을 디코딩하고 디코딩된 토큰 페이로드에 포함된 적절한 데이터를 결제 게이트웨이로 전송하여 결제를 처리합니다. |
기타 모든 결제 게이트웨이 (stripev2 포함) | 결제를 처리하려면 전체 base64 인코딩 토큰 문자열을 결제 게이트웨이 API로 전송합니다. Google Pay 결제 수단 토큰 구조에는 결제 게이트웨이가 복호화하여 결제를 처리할 수 있는 암호화된 필드가 포함되어 있습니다. |
디코딩된 페이로드 예시
다음 예는 다양한 결제 게이트웨이의 instrumentToken
필드에 반환된 디코딩된 페이로드를 보여줍니다.
이 JSON 예는 Braintree를 사용할 때 디코딩된 결제 토큰을 나타냅니다. nonce
필드의 값을 추출하고 값을 Braintree로 전송하여 결제를 처리합니다.
{ "androidPayCards": [{ "type": "AndroidPayCard", "nonce": "aeeb8297-4242...", "description": "AndroidPay", "consumed": false, "details": { "cardType": "Visa", "lastTwo": "29" } }] }
Braintree 제어 패널에서 Google Pay가 사용 설정되지 않은 경우 instrumentToken
필드가 다음 오류로 디코딩됩니다.
{ "error": { "message": "Record not found" }, "fieldErrors": [] }
이 JSON 예는 Stripe를 사용할 때 디코딩된 결제 토큰을 나타냅니다.
id
필드의 값을 추출하여 Stripe로 전송하여 결제를 처리합니다.
{ "id": "tok_abcdefg1234...", "object": "token", "card": { "id": "card_abcde...", "object": "card", "address_city": null, "address_country": null, "address_line1": null, "address_line1_check": null, "address_line2": null, "address_state": null, "address_zip": null, "address_zip_check": null, "brand": "Visa", "country": "US", "cvc_check": null, "dynamic_last4": "1234", "exp_month": 1, "exp_year": 2019, "funding": "credit", "last4": "1234", "metadata": {}, "name": null, "tokenization_method": "android_pay" }, "client_ip": "74.125.177.36", "created": 1500483670, "livemode": false, "type": "card", "used": false }
이 JSON 예는 stripev2를 사용할 때 디코딩된 결제 토큰을 나타냅니다.
{ "protocolVersion":"ECv2", "signature":"MEQCIH6Q4OwQ0jAceFEkGF0JID6sJNXxOEi4r+mA7biRxqBQAiAondqoUpU/bdsrAOpZIsrHQS9nwiiNwOrr24RyPeHA0Q\u003d\u003d", "intermediateSigningKey":{ "signedKey": "{\"keyExpiration\":\"1542323393147\",\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/1+3HBVSbdv+j7NaArdgMyoSAM43yRydzqdg1TxodSzA96Dj4Mc1EiKroxxunavVIvdxGnJeFViTzFvzFRxyCw\\u003d\\u003d\"}", "signatures": ["MEYCIQCO2EIi48s8VTH+ilMEpoXLFfkxAwHjfPSCVED/QDSHmQIhALLJmrUlNAY8hDQRV/y1iKZGsWpeNmIP+z+tCQHQxP0v"] }, "signedMessage":"{\"tag\":\"jpGz1F1Bcoi/fCNxI9n7Qrsw7i7KHrGtTf3NrRclt+U\\u003d\",\"ephemeralPublicKey\":\"BJatyFvFPPD21l8/uLP46Ta1hsKHndf8Z+tAgk+DEPQgYTkhHy19cF3h/bXs0tWTmZtnNm+vlVrKbRU9K8+7cZs\\u003d\",\"encryptedMessage\":\"mKOoXwi8OavZ\"}" }
이 JSON 예는 Square를 사용할 때 디코딩된 결제 토큰을 나타냅니다.
{ "signature": "MEYCIQCMAsWCrY2GfHM/gMAKiK3QCKJJOIkjZeTQGzcdWgvrhwIhAJ3mXwe+wmU9z+Apv1rTDsCVQBzayvWzT4ywxytrSPla", "protocolVersion": "ECv1", "signedMessage": "{\"encryptedMessage\":\"WkYz21EYxojwTqWh6A3oYXtmctu1PlqF+tNYPA4cq017nqj16Ge7kaVR7MI1XG1OrCmcMwP20u5Zb5E28XYan8UI8M4L120orvE9XU1ivZuO4Myq2O3ue8v0lY1MDx8Mnk+5mkAv1kLmzJc91gEQ2leIwrPuMDYqsQUHzTR3Jikh5/v+iWRkyQPKKxgj5c6Erdu/pkg1xV6fQJcHNdq9Jw11zl95x6eQurxw2Uy8v811azGr+noKJbw0uye72MkhmzMS5QKOzwGT9nBfO+zPLYSEewsdOcPbNZF94zk/KU9nxom/gQ+eYEMIZvOj9lO4gQqDqR6DyWyStk7MjeXQTvXWZBI1JpqvOrlTHL0Ct18RpbfOio7hAtafzb0NnqEKlsun+SSpJmvI7U6n6Cnu1JUMUGfT/Jsi6RJ3N6pRw2BubeR1925Xl3jXQnlz5io6X1YRlAcnshZyf6CjBpKES32aTf1m1IHRhZ2Jj6i/g7Y\\u003d\",\"ephemeralPublicKey\":\"BDQA0Cf//BHPcnB0R/GRrWa2g7T1QF97eOhAYy7l45M+kJnsoeL9OaUQV/KIMLvcgbmKkZIm2FQeL7ftd6S4q4c\\u003d\",\"tag\":\"DHtVyXNo+PDr7Thi/EjBBbsr2k7y1SwGIn0D9mmPTJc\\u003d\"}" }
토큰을 사용하여 결제를 처리하려면 source_id
필드에 gpay: 접두사가 추가된 Square의 결제 API에 대한 요청과 함께 base64 인코딩된 토큰 문자열을 반환합니다.
{ "idempotency_key": "ID", "source_id": "gpay:GOOGLE_PAY_BASE64_ENCODED_TOKEN", "amount_money": { "amount": 50, "currency": "USD" }, "location_id": "LOCATION_ID", "billing_address": { "postal_code": "11111" } }
다음은 Braintree에서 base64로 인코딩된 instrumentToken
를 디코딩하는 Node.js 예입니다.
function decodeToken(instrumentToken) { let decodedString = new Buffer(instrumentToken, 'base64').toString('ascii') if (decodedString.androidPayCards) { return decodedString.androidPayCards[0].nonce; } }