diff --git a/.env.test b/.env.test index 67237f2af2..75cb9063eb 100644 --- a/.env.test +++ b/.env.test @@ -2,5 +2,6 @@ # Override locally with `.env.test.local` SECRET_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +STRIPE_SECRET_TEST_API_KEY="bogus_key" SITE_URL="test.host" diff --git a/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/creates_a_payment_intent.yml b/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/creates_a_payment_intent.yml new file mode 100644 index 0000000000..f6217e943f --- /dev/null +++ b/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/creates_a_payment_intent.yml @@ -0,0 +1,130 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.stripe.com/v1/payment_intents + body: + encoding: UTF-8 + string: amount=1099¤cy=usd&payment_method_types[0]=card&metadata[order_id]=6735 + headers: + User-Agent: + - Stripe/v1 RubyBindings/7.1.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-Telemetry: + - '{"last_request_metrics":{"request_id":"req_topki4SXaxGGwg","request_duration_ms":1301}}' + X-Stripe-Client-User-Agent: + - '{"bindings_version":"7.1.0","lang":"ruby","lang_version":"3.0.3 p157 (2021-11-24)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 5.15.0-47-generic (buildd@lcy02-amd64-060) (gcc (Ubuntu 11.2.0-19ubuntu1) + 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #51-Ubuntu SMP Thu Aug 11 07:51:15 + UTC 2022","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, 20 Sep 2022 16:48:31 GMT + Content-Type: + - application/json + Content-Length: + - '1448' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, HEAD, OPTIONS, DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Idempotency-Key: + - 707e990e-8c39-4c2c-a041-d5837f66028a + Original-Request: + - req_BEYmwDryWum2vQ + Request-Id: + - req_BEYmwDryWum2vQ + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2019-11-05' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "pi_3Lk9cZKuuB1fWySn0ESKNLJ8", + "object": "payment_intent", + "amount": 1099, + "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": "automatic", + "charges": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/charges?payment_intent=pi_3Lk9cZKuuB1fWySn0ESKNLJ8" + }, + "client_secret": "pi_3Lk9cZKuuB1fWySn0ESKNLJ8_secret_5kWuLHVLm38pRmGgFEqlNkgB2", + "confirmation_method": "automatic", + "created": 1663692511, + "currency": "usd", + "customer": null, + "description": null, + "invoice": null, + "last_payment_error": null, + "livemode": false, + "metadata": { + "order_id": "6735" + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": 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, 20 Sep 2022 16:48:31 GMT +recorded_with: VCR 6.1.0 diff --git a/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/makes_a_payment.yml b/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/makes_a_payment.yml new file mode 100644 index 0000000000..3a6ba555ad --- /dev/null +++ b/spec/fixtures/vcr_cassettes/checking_out_an_order_with_a_Stripe_SCA_payment_method/when_the_user_submits_a_new_card_and_requests_that_the_card_is_saved_for_later/sends_a_request_to_stripe_API/makes_a_payment.yml @@ -0,0 +1,189 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.stripe.com/v1/charges + body: + encoding: UTF-8 + string: amount=2000¤cy=usd&source=tok_visa&metadata[order_id]=6735 + headers: + User-Agent: + - Stripe/v1 RubyBindings/7.1.0 + Authorization: + - Bearer + Content-Type: + - application/x-www-form-urlencoded + X-Stripe-Client-User-Agent: + - '{"bindings_version":"7.1.0","lang":"ruby","lang_version":"3.0.3 p157 (2021-11-24)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux + version 5.15.0-47-generic (buildd@lcy02-amd64-060) (gcc (Ubuntu 11.2.0-19ubuntu1) + 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #51-Ubuntu SMP Thu Aug 11 07:51:15 + UTC 2022","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, 20 Sep 2022 16:48:30 GMT + Content-Type: + - application/json + Content-Length: + - '3033' + Connection: + - keep-alive + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Methods: + - GET, POST, HEAD, OPTIONS, DELETE + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - Request-Id, Stripe-Manage-Version, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required + Access-Control-Max-Age: + - '300' + Cache-Control: + - no-cache, no-store + Idempotency-Key: + - 761bfeb4-7ee1-4c81-bf0d-1f85cc0949c0 + Original-Request: + - req_topki4SXaxGGwg + Request-Id: + - req_topki4SXaxGGwg + Stripe-Should-Retry: + - 'false' + Stripe-Version: + - '2019-11-05' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains; preload + body: + encoding: UTF-8 + string: |- + { + "id": "ch_3Lk9cXKuuB1fWySn0TI8AMrw", + "object": "charge", + "amount": 2000, + "amount_captured": 2000, + "amount_refunded": 0, + "application": null, + "application_fee": null, + "application_fee_amount": null, + "balance_transaction": "txn_3Lk9cXKuuB1fWySn0Ko2bgNN", + "billing_details": { + "address": { + "city": null, + "country": null, + "line1": null, + "line2": null, + "postal_code": null, + "state": null + }, + "email": null, + "name": null, + "phone": null + }, + "calculated_statement_descriptor": "OFNOFNOFN", + "captured": true, + "created": 1663692509, + "currency": "usd", + "customer": null, + "description": null, + "destination": null, + "dispute": null, + "disputed": false, + "failure_balance_transaction": null, + "failure_code": null, + "failure_message": null, + "fraud_details": {}, + "invoice": null, + "livemode": false, + "metadata": { + "order_id": "6735" + }, + "on_behalf_of": null, + "order": null, + "outcome": { + "network_status": "approved_by_network", + "reason": null, + "risk_level": "normal", + "risk_score": 42, + "seller_message": "Payment complete.", + "type": "authorized" + }, + "paid": true, + "payment_intent": null, + "payment_method": "card_1Lk9cXKuuB1fWySnABaPXBws", + "payment_method_details": { + "card": { + "brand": "visa", + "checks": { + "address_line1_check": null, + "address_postal_code_check": null, + "cvc_check": null + }, + "country": "US", + "exp_month": 9, + "exp_year": 2023, + "fingerprint": "6E6tgVjx6U65iHFV", + "funding": "credit", + "installments": null, + "last4": "4242", + "mandate": null, + "network": "visa", + "three_d_secure": null, + "wallet": null + }, + "type": "card" + }, + "receipt_email": null, + "receipt_number": null, + "receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xRmlxRXNLdXVCMWZXeVNuKN7dp5kGMgbN8weGDbs6LBZM2-baa3d6OcpNkyFBlD9ntXsZkBiC7cOLrRBSiMjTMmSYDpspP88klsk0", + "refunded": false, + "refunds": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/charges/ch_3Lk9cXKuuB1fWySn0TI8AMrw/refunds" + }, + "review": null, + "shipping": null, + "source": { + "id": "card_1Lk9cXKuuB1fWySnABaPXBws", + "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", + "customer": null, + "cvc_check": null, + "dynamic_last4": null, + "exp_month": 9, + "exp_year": 2023, + "fingerprint": "6E6tgVjx6U65iHFV", + "funding": "credit", + "last4": "4242", + "metadata": {}, + "name": null, + "tokenization_method": null + }, + "source_transfer": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "succeeded", + "transfer_data": null, + "transfer_group": null + } + recorded_at: Tue, 20 Sep 2022 16:48:30 GMT +recorded_with: VCR 6.1.0 diff --git a/spec/requests/checkout/stripe_sca_vcr_spec.rb b/spec/requests/checkout/stripe_sca_vcr_spec.rb new file mode 100644 index 0000000000..64e7106eeb --- /dev/null +++ b/spec/requests/checkout/stripe_sca_vcr_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'stripe' + +describe "checking out an order with a Stripe SCA payment method", type: :request do + include ShopWorkflow + include AuthenticationHelper + include OpenFoodNetwork::ApiHelper + include StripeHelper + include StripeStubs + + context "when the user submits a new card and requests that the card is saved for later" do + context "sends a request to stripe API", :vcr do + let(:secret) { ENV['STRIPE_SECRET_TEST_API_KEY'] } + + before do + Stripe.api_key = secret + end + + it "makes a payment" do + response = Stripe::Charge.create({ + amount: 2000, + currency: 'usd', + source: 'tok_visa', # obtained with Stripe.js + metadata: { order_id: '6735' }, + }) + end + + it "creates a payment intent" do + intent = Stripe::PaymentIntent.create({ + amount: 1099, + currency: 'usd', + payment_method_types: ['card'], + metadata: { + order_id: '6735', + }, + }) + end + end + end +end diff --git a/spec/support/vcr_setup.rb b/spec/support/vcr_setup.rb index c4a645cab4..550e179f57 100644 --- a/spec/support/vcr_setup.rb +++ b/spec/support/vcr_setup.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ENV["RAILS_ENV"] ||= 'test' require 'vcr' @@ -5,7 +7,6 @@ require 'vcr' VCR.configure do |config| config.cassette_library_dir = "spec/fixtures/vcr_cassettes" config.hook_into :webmock - config.default_cassette_options = { record: :once } config.ignore_localhost = true config.configure_rspec_metadata! end