mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
Merge pull request #6128 from luisramos0/stripe_bo
Add feature specs to stripe payments in the BackOffice
This commit is contained in:
@@ -553,10 +553,6 @@ module Spree
|
||||
line_item_adjustments.destroy_all
|
||||
end
|
||||
|
||||
def has_step?(step)
|
||||
checkout_steps.include?(step)
|
||||
end
|
||||
|
||||
def state_changed(name)
|
||||
state = "#{name}_state"
|
||||
return unless persisted?
|
||||
@@ -803,7 +799,6 @@ module Spree
|
||||
end
|
||||
|
||||
def has_available_shipment
|
||||
return unless has_step?("delivery")
|
||||
return unless address?
|
||||
return unless ship_address&.valid?
|
||||
# errors.add(:base, :no_shipping_methods_available) if available_shipping_methods.empty?
|
||||
|
||||
@@ -9,7 +9,6 @@ module Spree
|
||||
class_attribute :previous_states
|
||||
class_attribute :checkout_flow
|
||||
class_attribute :checkout_steps
|
||||
class_attribute :removed_transitions
|
||||
|
||||
def self.checkout_flow(&block)
|
||||
if block_given?
|
||||
@@ -24,7 +23,6 @@ module Spree
|
||||
self.checkout_steps = {}
|
||||
self.next_event_transitions = []
|
||||
self.previous_states = [:cart]
|
||||
self.removed_transitions = []
|
||||
|
||||
# Build the checkout flow using the checkout_flow defined either
|
||||
# within the Order class, or a decorator for that class.
|
||||
@@ -95,43 +93,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def self.insert_checkout_step(name, options = {})
|
||||
before = options.delete(:before)
|
||||
after = options.delete(:after) unless before
|
||||
after = checkout_steps.keys.last unless before || after
|
||||
|
||||
cloned_steps = checkout_steps.clone
|
||||
cloned_removed_transitions = removed_transitions.clone
|
||||
checkout_flow do
|
||||
cloned_steps.each_pair do |key, value|
|
||||
go_to_state(name, options) if key == before
|
||||
go_to_state(key, value)
|
||||
go_to_state(name, options) if key == after
|
||||
end
|
||||
cloned_removed_transitions.each do |transition|
|
||||
remove_transition(transition)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.remove_checkout_step(name)
|
||||
cloned_steps = checkout_steps.clone
|
||||
cloned_removed_transitions = removed_transitions.clone
|
||||
checkout_flow do
|
||||
cloned_steps.each_pair do |key, value|
|
||||
go_to_state(key, value) unless key == name
|
||||
end
|
||||
cloned_removed_transitions.each do |transition|
|
||||
remove_transition(transition)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.remove_transition(options = {})
|
||||
removed_transitions << options
|
||||
next_event_transitions.delete(find_transition(options))
|
||||
end
|
||||
|
||||
def self.find_transition(options = {})
|
||||
return nil if options.nil? || !options.include?(:from) || !options.include?(:to)
|
||||
|
||||
@@ -173,10 +134,6 @@ module Spree
|
||||
checkout_steps.index(step)
|
||||
end
|
||||
|
||||
def self.removed_transitions
|
||||
@removed_transitions ||= []
|
||||
end
|
||||
|
||||
def can_go_to_state?(state)
|
||||
return false unless self.state.present? &&
|
||||
checkout_step?(state) &&
|
||||
|
||||
@@ -30,31 +30,4 @@ feature '
|
||||
expect(page).to have_content "New Payment"
|
||||
end
|
||||
end
|
||||
|
||||
context "with a StripeSCA payment method" do
|
||||
before do
|
||||
stripe_payment_method = create(:stripe_sca_payment_method, distributors: [order.distributor])
|
||||
order.payments << create(:payment, payment_method: stripe_payment_method, order: order)
|
||||
end
|
||||
|
||||
it "renders the payment details" do
|
||||
login_as_admin_and_visit spree.admin_order_payments_path order
|
||||
|
||||
page.click_link("StripeSCA")
|
||||
expect(page).to have_content order.payments.last.source.last_digits
|
||||
end
|
||||
|
||||
context "with a deleted credit card" do
|
||||
before do
|
||||
order.payments.last.update_attribute(:source, nil)
|
||||
end
|
||||
|
||||
it "renders the payment details" do
|
||||
login_as_admin_and_visit spree.admin_order_payments_path order
|
||||
|
||||
page.click_link("StripeSCA")
|
||||
expect(page).to have_content order.payments.last.amount
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
161
spec/features/admin/payments_stripe_spec.rb
Normal file
161
spec/features/admin/payments_stripe_spec.rb
Normal file
@@ -0,0 +1,161 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
feature '
|
||||
As an hub manager
|
||||
I want to make Stripe payments
|
||||
' do
|
||||
include AuthenticationHelper
|
||||
include StripeHelper
|
||||
|
||||
let!(:order) { create(:completed_order_with_fees) }
|
||||
let!(:stripe_payment_method) do
|
||||
create(:stripe_sca_payment_method, distributors: [order.distributor])
|
||||
end
|
||||
let!(:stripe_account) do
|
||||
create(:stripe_account, enterprise: order.distributor, stripe_user_id: "abc123")
|
||||
end
|
||||
|
||||
before { setup_stripe }
|
||||
|
||||
context "making a new Stripe payment", js: true do
|
||||
before do
|
||||
stub_payment_methods_post_request
|
||||
stub_payment_intent_get_request
|
||||
end
|
||||
|
||||
context "for a complete order" do
|
||||
context "with a card that succeeds on card registration" do
|
||||
before { stub_payment_intents_post_request order: order, stripe_account_header: true }
|
||||
|
||||
context "and succeeds on payment capture" do
|
||||
before { stub_successful_capture_request order: order }
|
||||
|
||||
it "adds a payment with state complete" do
|
||||
login_as_admin_and_visit spree.new_admin_order_payment_path order
|
||||
|
||||
fill_in "payment_amount", with: order.total.to_s
|
||||
fill_in_card_details_in_backoffice
|
||||
click_button "Update"
|
||||
|
||||
expect(page).to have_link "StripeSCA"
|
||||
expect(OrderPaymentFinder.new(order.reload).last_payment.state).to eq "completed"
|
||||
end
|
||||
end
|
||||
|
||||
context "but fails on payment capture" do
|
||||
let(:error_message) { "Card was declined: insufficient funds." }
|
||||
|
||||
before { stub_failed_capture_request order: order, response: { message: error_message } }
|
||||
|
||||
it "fails to add a payment due to card error" do
|
||||
login_as_admin_and_visit spree.new_admin_order_payment_path order
|
||||
|
||||
fill_in "payment_amount", with: order.total.to_s
|
||||
fill_in_card_details_in_backoffice
|
||||
click_button "Update"
|
||||
|
||||
expect(page).to have_link "StripeSCA"
|
||||
expect(page).to have_content "FAILED"
|
||||
expect(OrderPaymentFinder.new(order.reload).last_payment.state).to eq "failed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with a card that fails on registration because it requires(redirects) extra auth" do
|
||||
before do
|
||||
stub_payment_intents_post_request_with_redirect order: order,
|
||||
redirect_url: "www.dummy.org"
|
||||
end
|
||||
|
||||
it "fails to add a payment due to card error" do
|
||||
login_as_admin_and_visit spree.new_admin_order_payment_path order
|
||||
|
||||
fill_in "payment_amount", with: order.total.to_s
|
||||
fill_in_card_details_in_backoffice
|
||||
click_button "Update"
|
||||
|
||||
expect(page).to have_link "StripeSCA"
|
||||
expect(page).to have_content "PROCESSING"
|
||||
expect(OrderPaymentFinder.new(order.reload).last_payment.state).to eq "processing"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "for an order in payment state" do
|
||||
let!(:order) { create(:order_with_line_items, distributor: create(:enterprise)) }
|
||||
|
||||
before do
|
||||
stub_payment_intents_post_request order: order, stripe_account_header: true
|
||||
stub_successful_capture_request order: order
|
||||
|
||||
while !order.payment? do break unless order.next! end
|
||||
end
|
||||
|
||||
it "adds a payment with state complete" do
|
||||
login_as_admin_and_visit spree.new_admin_order_payment_path order
|
||||
|
||||
fill_in "payment_amount", with: order.total.to_s
|
||||
fill_in_card_details_in_backoffice
|
||||
click_button "Update"
|
||||
|
||||
expect(page).to have_link "StripeSCA"
|
||||
expect(OrderPaymentFinder.new(order.reload).last_payment.state).to eq "completed"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with a payment using a StripeSCA payment method" do
|
||||
before do
|
||||
order.update payments: []
|
||||
order.payments << create(:payment, payment_method: stripe_payment_method, order: order)
|
||||
end
|
||||
|
||||
it "renders the payment details" do
|
||||
login_as_admin_and_visit spree.admin_order_payments_path order
|
||||
|
||||
page.click_link("StripeSCA")
|
||||
expect(page).to have_content order.payments.last.source.last_digits
|
||||
end
|
||||
|
||||
context "with a deleted credit card" do
|
||||
before do
|
||||
order.payments.last.update source: nil
|
||||
end
|
||||
|
||||
it "renders the payment details" do
|
||||
login_as_admin_and_visit spree.admin_order_payments_path order
|
||||
|
||||
page.click_link("StripeSCA")
|
||||
expect(page).to have_content order.payments.last.amount
|
||||
end
|
||||
end
|
||||
|
||||
context "that is completed", js: true do
|
||||
let(:payment) { OrderPaymentFinder.new(order.reload).last_payment }
|
||||
|
||||
before do
|
||||
stub_payment_intent_get_request stripe_account_header: false
|
||||
stub_successful_capture_request order: order
|
||||
|
||||
payment.update response_code: "pi_123", amount: order.total
|
||||
payment.purchase!
|
||||
|
||||
stub_refund_request
|
||||
end
|
||||
|
||||
it "allows to refund the payment" do
|
||||
login_as_admin_and_visit spree.admin_order_payments_path order
|
||||
|
||||
expect(page).to have_link "StripeSCA"
|
||||
expect(page).to have_content "COMPLETED"
|
||||
|
||||
page.find('a.icon-void').click
|
||||
|
||||
expect(page).to have_content "VOID"
|
||||
expect(payment.reload.state).to eq "void"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -93,7 +93,7 @@ feature "Check out with Stripe", js: true do
|
||||
context "with guest checkout" do
|
||||
before do
|
||||
stub_payment_intent_get_request
|
||||
stub_hub_payment_methods_request
|
||||
stub_payment_methods_post_request
|
||||
end
|
||||
|
||||
context "when the card is accepted" do
|
||||
@@ -127,21 +127,10 @@ feature "Check out with Stripe", js: true do
|
||||
end
|
||||
|
||||
context "when the card needs extra SCA authorization", js: true do
|
||||
let(:stripe_redirect_url) { checkout_path(payment_intent: "pi_123") }
|
||||
let(:payment_intent_authorize_response) do
|
||||
{ status: 200, body: JSON.generate(id: "pi_123",
|
||||
object: "payment_intent",
|
||||
next_source_action: {
|
||||
type: "authorize_with_url",
|
||||
authorize_with_url: { url: stripe_redirect_url }
|
||||
},
|
||||
status: "requires_source_action") }
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_intents")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/)
|
||||
.to_return(payment_intent_authorize_response)
|
||||
stripe_redirect_url = checkout_path(payment_intent: "pi_123")
|
||||
stub_payment_intents_post_request_with_redirect order: order,
|
||||
redirect_url: stripe_redirect_url
|
||||
end
|
||||
|
||||
describe "and the authorization succeeds" do
|
||||
|
||||
@@ -13,24 +13,23 @@ module OpenFoodNetwork
|
||||
@variant1 = create(:variant)
|
||||
@variant1.product.supplier = @supplier1
|
||||
@variant1.product.save!
|
||||
@variant1.reload
|
||||
|
||||
shipping_instructions = "pick up on thursday please!"
|
||||
|
||||
order1 = create(:order, distributor: distributor, bill_address: bill_address, special_instructions: shipping_instructions)
|
||||
line_item11 = create(:line_item, variant: @variant1, order: order1)
|
||||
order1.line_items << line_item11
|
||||
@orders << order1
|
||||
@orders << order1.reload
|
||||
|
||||
order2 = create(:order, distributor: distributor, bill_address: bill_address, special_instructions: shipping_instructions)
|
||||
line_item21 = create(:line_item, variant: @variant1, order: order2)
|
||||
order2.line_items << line_item21
|
||||
|
||||
@variant2 = create(:variant)
|
||||
@variant2.product.supplier = @supplier1
|
||||
@variant2.product.save!
|
||||
|
||||
line_item22 = create(:line_item, variant: @variant2, order: order2)
|
||||
order2.line_items << line_item22
|
||||
@orders << order2
|
||||
@orders << order2.reload
|
||||
|
||||
@supplier2 = create(:supplier_enterprise)
|
||||
@variant3 = create(:variant, weight: nil)
|
||||
@@ -39,8 +38,7 @@ module OpenFoodNetwork
|
||||
|
||||
order3 = create(:order, distributor: distributor, bill_address: bill_address, special_instructions: shipping_instructions)
|
||||
line_item31 = create(:line_item, variant: @variant3, order: order3)
|
||||
order3.line_items << line_item31
|
||||
@orders << order3
|
||||
@orders << order3.reload
|
||||
end
|
||||
|
||||
it "should return a header row describing the report" do
|
||||
|
||||
@@ -10,9 +10,7 @@ module Spree
|
||||
let!(:line_item2) { create(:line_item, order: order) }
|
||||
|
||||
before do
|
||||
order.line_items << line_item
|
||||
order.line_items << line_item2
|
||||
order.shipments = [shipment]
|
||||
order.reload.shipments = [shipment]
|
||||
end
|
||||
|
||||
describe "#line_items_for" do
|
||||
|
||||
@@ -30,16 +30,6 @@ describe Spree::Order::Checkout do
|
||||
expect(Spree::Order.find_transition({ foo: :bar, baz: :dog })).to be_falsy
|
||||
end
|
||||
|
||||
it '.remove_transition' do
|
||||
options = { from: transitions.first.keys.first, to: transitions.first.values.first }
|
||||
allow(Spree::Order).to receive(:next_event_transition).and_return([options])
|
||||
expect(Spree::Order.remove_transition(options)).to be_truthy
|
||||
end
|
||||
|
||||
it '.remove_transition when contract was broken' do
|
||||
expect(Spree::Order.remove_transition(nil)).to be_falsy
|
||||
end
|
||||
|
||||
context "#checkout_steps" do
|
||||
context "when payment not required" do
|
||||
before { allow(order).to receive_messages payment_required?: false }
|
||||
@@ -160,145 +150,6 @@ describe Spree::Order::Checkout do
|
||||
end
|
||||
end
|
||||
|
||||
context "subclassed order" do
|
||||
# This causes another test above to fail, but fixing this test should make
|
||||
# the other test pass
|
||||
class SubclassedOrder < Spree::Order
|
||||
checkout_flow do
|
||||
go_to_state :payment
|
||||
go_to_state :complete
|
||||
end
|
||||
end
|
||||
|
||||
it "should only call default transitions once when checkout_flow is redefined" do
|
||||
order = SubclassedOrder.new
|
||||
allow(order).to receive_messages payment_required?: true
|
||||
expect(order).to receive(:process_payments!).once
|
||||
order.state = "payment"
|
||||
order.next!
|
||||
expect(order.state).to eq "complete"
|
||||
end
|
||||
end
|
||||
|
||||
context "re-define checkout flow" do
|
||||
before do
|
||||
@old_checkout_flow = Spree::Order.checkout_flow
|
||||
Spree::Order.class_eval do
|
||||
checkout_flow do
|
||||
go_to_state :payment
|
||||
go_to_state :complete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Spree::Order.checkout_flow(&@old_checkout_flow)
|
||||
end
|
||||
|
||||
it "should not keep old event transitions when checkout_flow is redefined" do
|
||||
expect(Spree::Order.next_event_transitions).to eq [{ cart: :payment }, { payment: :complete }]
|
||||
end
|
||||
|
||||
it "should not keep old events when checkout_flow is redefined" do
|
||||
state_machine = Spree::Order.state_machine
|
||||
expect(state_machine.states.any? { |s| s.name == :address }).to be_falsy
|
||||
known_states = state_machine.events[:next].branches.map(&:known_states).flatten
|
||||
expect(known_states).to_not include(:address)
|
||||
expect(known_states).to_not include(:delivery)
|
||||
expect(known_states).to_not include(:confirm)
|
||||
end
|
||||
end
|
||||
|
||||
# Regression test for Spree #3665
|
||||
context "with only a complete step" do
|
||||
before do
|
||||
@old_checkout_flow = Spree::Order.checkout_flow
|
||||
Spree::Order.class_eval do
|
||||
checkout_flow do
|
||||
go_to_state :complete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Spree::Order.checkout_flow(&@old_checkout_flow)
|
||||
end
|
||||
|
||||
it "does not attempt to process payments" do
|
||||
allow(order).to receive_message_chain(:line_items, :present?).and_return(true)
|
||||
expect(order).to_not receive(:payment_required?)
|
||||
expect(order).to_not receive(:process_payments!)
|
||||
order.next!
|
||||
end
|
||||
end
|
||||
|
||||
context "insert checkout step" do
|
||||
before do
|
||||
@old_checkout_flow = Spree::Order.checkout_flow
|
||||
Spree::Order.class_eval do
|
||||
insert_checkout_step :new_step, before: :address
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Spree::Order.checkout_flow(&@old_checkout_flow)
|
||||
end
|
||||
|
||||
it "should maintain removed transitions" do
|
||||
transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
|
||||
expect(transition).to be_nil
|
||||
end
|
||||
|
||||
context "before" do
|
||||
before do
|
||||
Spree::Order.class_eval do
|
||||
insert_checkout_step :before_address, before: :address
|
||||
end
|
||||
end
|
||||
|
||||
specify do
|
||||
order = Spree::Order.new
|
||||
expect(order.checkout_steps).to eq %w(new_step before_address address delivery complete)
|
||||
end
|
||||
end
|
||||
|
||||
context "after" do
|
||||
before do
|
||||
Spree::Order.class_eval do
|
||||
insert_checkout_step :after_address, after: :address
|
||||
end
|
||||
end
|
||||
|
||||
specify do
|
||||
order = Spree::Order.new
|
||||
expect(order.checkout_steps).to eq %w(new_step address after_address delivery complete)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "remove checkout step" do
|
||||
before do
|
||||
@old_checkout_flow = Spree::Order.checkout_flow
|
||||
Spree::Order.class_eval do
|
||||
remove_checkout_step :address
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Spree::Order.checkout_flow(&@old_checkout_flow)
|
||||
end
|
||||
|
||||
it "should maintain removed transitions" do
|
||||
transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
|
||||
expect(transition).to be_nil
|
||||
end
|
||||
|
||||
specify do
|
||||
order = Spree::Order.new
|
||||
expect(order.checkout_steps).to eq %w(delivery complete)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'event :restart_checkout' do
|
||||
let(:order) { build_stubbed(:order) }
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ describe OrderCheckoutRestart do
|
||||
order.update_attribute(:state, "payment")
|
||||
end
|
||||
|
||||
xcontext "when order ship address is nil" do
|
||||
context "when order ship address is nil" do
|
||||
before { order.ship_address = nil }
|
||||
|
||||
it "resets the order state, and clears incomplete shipments and payments" do
|
||||
@@ -33,7 +33,7 @@ describe OrderCheckoutRestart do
|
||||
end
|
||||
end
|
||||
|
||||
xcontext "when order ship address is not empty" do
|
||||
context "when order ship address is not empty" do
|
||||
before { order.ship_address = order.address_from_distributor }
|
||||
|
||||
it "resets the order state, and clears incomplete shipments and payments" do
|
||||
|
||||
@@ -21,16 +21,31 @@ module StripeHelper
|
||||
fill_in 'CVC', with: '123'
|
||||
end
|
||||
|
||||
def fill_in_card_details_in_backoffice
|
||||
choose "StripeSCA"
|
||||
fill_in "cardholder_name", with: "David Gilmour"
|
||||
fill_in "stripe-cardnumber", with: "4242424242424242"
|
||||
fill_in "exp-date", with: "01-01-2050"
|
||||
fill_in "cvc", with: "678"
|
||||
end
|
||||
|
||||
def setup_stripe
|
||||
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
|
||||
allow(Stripe).to receive(:publishable_key) { "pk_test_12345" }
|
||||
Spree::Config.set(stripe_connect_enabled: true)
|
||||
end
|
||||
|
||||
def stub_payment_intents_post_request(order:, response: {})
|
||||
def stub_payment_intents_post_request(order:, response: {}, stripe_account_header: true)
|
||||
stub = stub_request(:post, "https://api.stripe.com/v1/payment_intents")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/)
|
||||
stub = stub.with(headers: { 'Stripe-Account' => 'abc123' }) if stripe_account_header
|
||||
stub.to_return(payment_intent_authorize_response_mock(response))
|
||||
end
|
||||
|
||||
def stub_payment_intents_post_request_with_redirect(order:, redirect_url:)
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_intents")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/)
|
||||
.to_return(payment_intent_authorize_response_mock(response))
|
||||
.to_return(payment_intent_redirect_response_mock(redirect_url))
|
||||
end
|
||||
|
||||
def stub_payment_intent_get_request(response: {}, stripe_account_header: true)
|
||||
@@ -39,7 +54,7 @@ module StripeHelper
|
||||
stub.to_return(payment_intent_authorize_response_mock(response))
|
||||
end
|
||||
|
||||
def stub_hub_payment_methods_request(response: {})
|
||||
def stub_payment_methods_post_request(response: {})
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_methods")
|
||||
.with(body: { payment_method: "pm_123" },
|
||||
headers: { 'Stripe-Account' => 'abc123' })
|
||||
@@ -61,6 +76,13 @@ module StripeHelper
|
||||
.to_return(response_mock)
|
||||
end
|
||||
|
||||
def stub_refund_request
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds")
|
||||
.with(body: { amount: 2000, expand: ["charge"] },
|
||||
headers: { 'Stripe-Account' => 'abc123' })
|
||||
.to_return(payment_successful_refund_mock)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def payment_intent_authorize_response_mock(options)
|
||||
@@ -74,6 +96,16 @@ module StripeHelper
|
||||
charges: { data: [{ id: "ch_1234", amount: 2000 }] }) }
|
||||
end
|
||||
|
||||
def payment_intent_redirect_response_mock(redirect_url)
|
||||
{ status: 200, body: JSON.generate(id: "pi_123",
|
||||
object: "payment_intent",
|
||||
next_source_action: {
|
||||
type: "authorize_with_url",
|
||||
authorize_with_url: { url: redirect_url }
|
||||
},
|
||||
status: "requires_source_action") }
|
||||
end
|
||||
|
||||
def payment_successful_capture_mock(options)
|
||||
{ status: options[:code] || 200,
|
||||
body: JSON.generate(object: "payment_intent",
|
||||
@@ -91,4 +123,11 @@ module StripeHelper
|
||||
{ status: options[:code] || 200,
|
||||
body: JSON.generate(id: "pm_456", customer: "cus_A123") }
|
||||
end
|
||||
|
||||
def payment_successful_refund_mock
|
||||
{ status: 200,
|
||||
body: JSON.generate(object: "refund",
|
||||
amount: 2000,
|
||||
charge: "ch_1234") }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user