diff --git a/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_contains_an_error/raises_Stripe_error_with_payment_intent_last_payment_error_as_message.yml b/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_contains_an_error/raises_Stripe_error_with_payment_intent_last_payment_error_as_message.yml new file mode 100644 index 0000000000..8b436f5f9d --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_contains_an_error/raises_Stripe_error_with_payment_intent_last_payment_error_as_message.yml @@ -0,0 +1,687 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.stripe.com/v1/payment_methods + body: + encoding: UTF-8 + string: type=card&card[number]=4000000000009995&card[exp_month]=12&card[exp_year]=2034&card[cvc]=314 + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_MhJwK3bCx1nUCV","request_duration_ms":399}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:51 GMT + Content-Type: + - application/json + Content-Length: + - '931' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_methods; block-all-mixed-content; + default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; + img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' + Idempotency-Key: + - cae4cabe-d698-4d9a-a559-c7adee3b5919 + Original-Request: + - req_4u0uONl4HDoqTP + Request-Id: + - req_4u0uONl4HDoqTP + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pm_1O7NDDKuuB1fWySnK7zLU5xt", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "unchecked" + }, + "country": "US", + "exp_month": 12, + "exp_year": 2034, + "fingerprint": "O0I0muUGQBJy3p73", + "funding": "credit", + "generated_from": null, + "last4": "9995", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1698778971, + "customer": null, + "livemode": false, + "metadata": {}, + "type": "card" + } + recorded_at: Tue, 31 Oct 2023 19:02:51 GMT +- request: + method: post + uri: https://api.stripe.com/v1/payment_intents + body: + encoding: UTF-8 + string: amount=100¤cy=eur&payment_method=pm_1O7NDDKuuB1fWySnK7zLU5xt&payment_method_types[0]=card&capture_method=manual + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_4u0uONl4HDoqTP","request_duration_ms":467}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:52 GMT + Content-Type: + - application/json + Content-Length: + - '1343' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents; block-all-mixed-content; + default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; + img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' + Idempotency-Key: + - 2aa0ddf3-7314-4037-b01b-94d35ccd0468 + Original-Request: + - req_Tce1DG0Fz2T18d + Request-Id: + - req_Tce1DG0Fz2T18d + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3O7NDDKuuB1fWySn0NkcMDXT", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDDKuuB1fWySn0NkcMDXT_secret_x4X665Kf2HS7eo6jcMjtLrmcO", + "confirmation_method": "automatic", + "created": 1698778971, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": null, + "latest_charge": null, + "livemode": false, + "metadata": {}, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1O7NDDKuuB1fWySnK7zLU5xt", + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_confirmation", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 31 Oct 2023 19:02:52 GMT +- request: + method: post + uri: https://api.stripe.com/v1/payment_intents/pi_3O7NDDKuuB1fWySn0NkcMDXT/confirm + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_Tce1DG0Fz2T18d","request_duration_ms":403}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 402 + message: Payment Required + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:53 GMT + Content-Type: + - application/json + Content-Length: + - '4736' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents%2F%3Aintent%2Fconfirm; + block-all-mixed-content; default-src 'none'; base-uri 'none'; form-action + 'none'; frame-ancestors 'none'; img-src 'self'; script-src 'self' 'report-sample'; + style-src 'self' + Idempotency-Key: + - 8eef3458-d952-4f5f-be7d-51a1ba26ea4e + Original-Request: + - req_4PX7kfhZVXH2V1 + Request-Id: + - req_4PX7kfhZVXH2V1 + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: | + { + "error": { + "charge": "ch_3O7NDDKuuB1fWySn0iydIyVy", + "code": "card_declined", + "decline_code": "insufficient_funds", + "doc_url": "https://stripe.com/docs/error-codes/card-declined", + "message": "Your card has insufficient funds.", + "payment_intent": { + "id": "pi_3O7NDDKuuB1fWySn0NkcMDXT", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 0, + "amount_details": { + "tip": { + } + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDDKuuB1fWySn0NkcMDXT_secret_x4X665Kf2HS7eo6jcMjtLrmcO", + "confirmation_method": "automatic", + "created": 1698778971, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": { + "charge": "ch_3O7NDDKuuB1fWySn0iydIyVy", + "code": "card_declined", + "decline_code": "insufficient_funds", + "doc_url": "https://stripe.com/docs/error-codes/card-declined", + "message": "Your card has insufficient funds.", + "payment_method": { + "id": "pm_1O7NDDKuuB1fWySnK7zLU5xt", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "pass" + }, + "country": "US", + "exp_month": 12, + "exp_year": 2034, + "fingerprint": "O0I0muUGQBJy3p73", + "funding": "credit", + "generated_from": null, + "last4": "9995", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1698778971, + "customer": null, + "livemode": false, + "metadata": { + }, + "type": "card" + }, + "type": "card_error" + }, + "latest_charge": "ch_3O7NDDKuuB1fWySn0iydIyVy", + "livemode": false, + "metadata": { + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": null, + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_payment_method", + "transfer_data": null, + "transfer_group": null + }, + "payment_method": { + "id": "pm_1O7NDDKuuB1fWySnK7zLU5xt", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "pass" + }, + "country": "US", + "exp_month": 12, + "exp_year": 2034, + "fingerprint": "O0I0muUGQBJy3p73", + "funding": "credit", + "generated_from": null, + "last4": "9995", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1698778971, + "customer": null, + "livemode": false, + "metadata": { + }, + "type": "card" + }, + "request_log_url": "https://dashboard.stripe.com/test/logs/req_4PX7kfhZVXH2V1?t=1698778972", + "type": "card_error" + } + } + recorded_at: Tue, 31 Oct 2023 19:02:53 GMT +- request: + method: get + uri: https://api.stripe.com/v1/payment_intents/pi_3O7NDDKuuB1fWySn0NkcMDXT + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_Tce1DG0Fz2T18d","request_duration_ms":403}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:53 GMT + Content-Type: + - application/json + Content-Length: + - '2741' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents%2F%3Aintent; + block-all-mixed-content; default-src 'none'; base-uri 'none'; form-action + 'none'; frame-ancestors 'none'; img-src 'self'; script-src 'self' 'report-sample'; + style-src 'self' + Request-Id: + - req_rC5iv8iHUH5Bx9 + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3O7NDDKuuB1fWySn0NkcMDXT", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDDKuuB1fWySn0NkcMDXT_secret_x4X665Kf2HS7eo6jcMjtLrmcO", + "confirmation_method": "automatic", + "created": 1698778971, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": { + "charge": "ch_3O7NDDKuuB1fWySn0iydIyVy", + "code": "card_declined", + "decline_code": "insufficient_funds", + "doc_url": "https://stripe.com/docs/error-codes/card-declined", + "message": "Your card has insufficient funds.", + "payment_method": { + "id": "pm_1O7NDDKuuB1fWySnK7zLU5xt", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "pass" + }, + "country": "US", + "exp_month": 12, + "exp_year": 2034, + "fingerprint": "O0I0muUGQBJy3p73", + "funding": "credit", + "generated_from": null, + "last4": "9995", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1698778971, + "customer": null, + "livemode": false, + "metadata": {}, + "type": "card" + }, + "type": "card_error" + }, + "latest_charge": "ch_3O7NDDKuuB1fWySn0iydIyVy", + "livemode": false, + "metadata": {}, + "next_action": null, + "on_behalf_of": null, + "payment_method": null, + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_payment_method", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 31 Oct 2023 19:02:53 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_is_valid/returns_payment_intent_id_and_does_not_raise.yml b/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_is_valid/returns_payment_intent_id_and_does_not_raise.yml new file mode 100644 index 0000000000..8d565e0a9d --- /dev/null +++ b/spec/fixtures/vcr_cassettes/Stripe_PaymentIntentValidator/_call/when_payment_intent_is_valid/returns_payment_intent_id_and_does_not_raise.yml @@ -0,0 +1,515 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.stripe.com/v1/payment_methods + body: + encoding: UTF-8 + string: type=card&card[number]=4242424242424242&card[exp_month]=12&card[exp_year]=2034&card[cvc]=314 + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:48 GMT + Content-Type: + - application/json + Content-Length: + - '931' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_methods; block-all-mixed-content; + default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; + img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' + Idempotency-Key: + - fe964a69-e54d-4063-9de0-9279a4687132 + Original-Request: + - req_nN1oUfa5UXec44 + Request-Id: + - req_nN1oUfa5UXec44 + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pm_1O7ND9KuuB1fWySnmyW2YCGo", + "object": "payment_method", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": "unchecked" + }, + "country": "US", + "exp_month": 12, + "exp_year": 2034, + "fingerprint": "6E6tgVjx6U65iHFV", + "funding": "credit", + "generated_from": null, + "last4": "4242", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1698778967, + "customer": null, + "livemode": false, + "metadata": {}, + "type": "card" + } + recorded_at: Tue, 31 Oct 2023 19:02:48 GMT +- request: + method: post + uri: https://api.stripe.com/v1/payment_intents + body: + encoding: UTF-8 + string: amount=100¤cy=eur&payment_method=pm_1O7ND9KuuB1fWySnmyW2YCGo&payment_method_types[0]=card&capture_method=manual + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_nN1oUfa5UXec44","request_duration_ms":789}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:48 GMT + Content-Type: + - application/json + Content-Length: + - '1343' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents; block-all-mixed-content; + default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; + img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' + Idempotency-Key: + - 7d125bdc-3da1-4b3a-bdda-ec7acc82ac75 + Original-Request: + - req_GJrd6HK4e2UZdK + Request-Id: + - req_GJrd6HK4e2UZdK + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3O7NDAKuuB1fWySn0EzngPdL", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDAKuuB1fWySn0EzngPdL_secret_nvyKe0sDpd5nsmKu485lNtGl3", + "confirmation_method": "automatic", + "created": 1698778968, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": null, + "latest_charge": null, + "livemode": false, + "metadata": {}, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1O7ND9KuuB1fWySnmyW2YCGo", + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_confirmation", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 31 Oct 2023 19:02:48 GMT +- request: + method: post + uri: https://api.stripe.com/v1/payment_intents/pi_3O7NDAKuuB1fWySn0EzngPdL/confirm + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_GJrd6HK4e2UZdK","request_duration_ms":609}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:49 GMT + Content-Type: + - application/json + Content-Length: + - '1365' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents%2F%3Aintent%2Fconfirm; + block-all-mixed-content; default-src 'none'; base-uri 'none'; form-action + 'none'; frame-ancestors 'none'; img-src 'self'; script-src 'self' 'report-sample'; + style-src 'self' + Idempotency-Key: + - 8f195fa2-ecd1-403b-b70e-9b4d9a768a09 + Original-Request: + - req_nWd6JD2SbU0eH6 + Request-Id: + - req_nWd6JD2SbU0eH6 + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3O7NDAKuuB1fWySn0EzngPdL", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 100, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDAKuuB1fWySn0EzngPdL_secret_nvyKe0sDpd5nsmKu485lNtGl3", + "confirmation_method": "automatic", + "created": 1698778968, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": null, + "latest_charge": "ch_3O7NDAKuuB1fWySn01eDFLcJ", + "livemode": false, + "metadata": {}, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1O7ND9KuuB1fWySnmyW2YCGo", + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_capture", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 31 Oct 2023 19:02:49 GMT +- request: + method: get + uri: https://api.stripe.com/v1/payment_intents/pi_3O7NDAKuuB1fWySn0EzngPdL + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Stripe/v1 RubyBindings/10.0.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_nWd6JD2SbU0eH6","request_duration_ms":922}}' + Stripe-Version: + - '2023-10-16' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"10.0.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 + (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) + #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 6 10:23:26 UTC 2","hostname":"ff-LAT"}' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Tue, 31 Oct 2023 19:02:51 GMT + Content-Type: + - application/json + Content-Length: + - '1365' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET,HEAD,PUT,PATCH,POST,DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, + X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Content-Security-Policy-Report-Only: + - report-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_intents%2F%3Aintent; + block-all-mixed-content; default-src 'none'; base-uri 'none'; form-action + 'none'; frame-ancestors 'none'; img-src 'self'; script-src 'self' 'report-sample'; + style-src 'self' + Request-Id: + - req_MhJwK3bCx1nUCV + Stripe-Version: + - '2023-10-16' + Vary: + - Origin + X-Stripe-Routing-Context-Priority-Tier: + - api-testmode + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3O7NDAKuuB1fWySn0EzngPdL", + "object": "payment_intent", + "amount": 100, + "amount_capturable": 100, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "manual", + "client_secret": "pi_3O7NDAKuuB1fWySn0EzngPdL_secret_nvyKe0sDpd5nsmKu485lNtGl3", + "confirmation_method": "automatic", + "created": 1698778968, + "currency": "eur", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": null, + "latest_charge": "ch_3O7NDAKuuB1fWySn01eDFLcJ", + "livemode": false, + "metadata": {}, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1O7ND9KuuB1fWySnmyW2YCGo", + "payment_method_configuration_details": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_capture", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 31 Oct 2023 19:02:51 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/lib/stripe/payment_intent_validator_spec.rb b/spec/lib/stripe/payment_intent_validator_spec.rb index 12287bafe6..bb0f95ea2b 100644 --- a/spec/lib/stripe/payment_intent_validator_spec.rb +++ b/spec/lib/stripe/payment_intent_validator_spec.rb @@ -5,30 +5,58 @@ require 'stripe/payment_intent_validator' module Stripe describe PaymentIntentValidator do - describe "#call" do + let(:secret) { ENV.fetch('STRIPE_SECRET_TEST_API_KEY', nil) } + + let(:payment_method) { + create(:stripe_sca_payment_method, distributor_ids: [create(:distributor_enterprise).id], + preferred_enterprise_id: create(:enterprise).id) + } + let(:source) { + create(:credit_card) + } + + before do + Stripe.api_key = secret + end + + describe "#call", :vcr do + let(:payment) { + create(:payment, amount: payment_intent.amount, payment_method:, + response_code: payment_intent.id, source:) + } let(:validator) { Stripe::PaymentIntentValidator.new(payment) } - let(:payment) { build(:payment, response_code: payment_intent_id) } - let(:payment_intent_id) { "pi_123" } - let(:stripe_account_id) { "abc123" } - let(:stripe_account_mock) { double(stripe_user_id: stripe_account_id) } - let(:payment_intent_response_mock) { { status: 200, body: payment_intent_response_body } } - - before do - Stripe.api_key = "sk_test_12345" - - allow(payment).to receive_message_chain(:payment_method, :preferred_enterprise_id) { 1 } - allow(StripeAccount).to receive(:find_by) { stripe_account_mock } - - stub_request(:get, "https://api.stripe.com/v1/payment_intents/#{payment_intent_id}") - .with(headers: { 'Stripe-Account' => stripe_account_id }) - .to_return(payment_intent_response_mock) - end context "when payment intent is valid" do + let!(:pm_card) do + Stripe::PaymentMethod.create({ + type: 'card', + card: { + number: '4242424242424242', + exp_month: 12, + exp_year: 2034, + cvc: '314', + }, + }) + end + + let!(:payment_intent) do + Stripe::PaymentIntent.create({ + amount: 100, + currency: 'eur', + payment_method: pm_card, + payment_method_types: ['card'], + capture_method: 'manual', + }) + end + let(:payment_intent_response_body) { - JSON.generate(id: payment_intent_id, status: "requires_capture") + [id: payment_intent.id, status: payment_intent.status] } + before do + Stripe::PaymentIntent.confirm(payment_intent.id) + end + it "returns payment intent id and does not raise" do expect { result = validator.call @@ -38,14 +66,41 @@ module Stripe end context "when payment intent contains an error" do + let!(:pm_card) do + Stripe::PaymentMethod.create({ + type: 'card', + card: { + # decline code: insufficient_funds + number: '4000000000009995', + exp_month: 12, + exp_year: 2034, + cvc: '314', + }, + }) + end + + let!(:payment_intent) do + Stripe::PaymentIntent.create({ + amount: 100, + currency: 'eur', + payment_method: pm_card, + payment_method_types: ['card'], + capture_method: 'manual', + }) + end + let(:payment_intent_response_body) { JSON.generate(id: payment_intent_id, last_payment_error: { message: "No money" }) } it "raises Stripe error with payment intent last_payment_error as message" do + expect { + Stripe::PaymentIntent.confirm(payment_intent.id) + }.to raise_error Stripe::StripeError, "Your card has insufficient funds." + expect { validator.call - }.to raise_error Stripe::StripeError, "No money" + }.to raise_error Stripe::StripeError, "Your card has insufficient funds." end end end