Add test for #credit

it uses ActiveMerchant::Billing::StripePaymentIntentsGateway#refund,
we covering the last scenario that previously used the decorator.
This commit is contained in:
Gaetan Craig-Riou
2024-02-13 10:43:49 +11:00
parent 549610bc35
commit 0af9ccd17a
2 changed files with 778 additions and 0 deletions

View File

@@ -0,0 +1,747 @@
---
http_interactions:
- request:
method: post
uri: https://api.stripe.com/v1/payment_intents
body:
encoding: UTF-8
string: amount=1000&currency=aud&payment_method=pm_card_mastercard&payment_method_types[0]=card&capture_method=automatic&confirm=true
headers:
User-Agent:
- Stripe/v1 RubyBindings/10.6.0
Authorization:
- Bearer <HIDDEN-STRIPE_INSTANCE_SECRET_KEY>
Content-Type:
- application/x-www-form-urlencoded
Stripe-Version:
- '2023-10-16'
X-Stripe-Client-User-Agent:
- '{"bindings_version":"10.6.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux
version 5.15.0-92-generic (buildd@lcy02-amd64-002) (gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2)
9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #102~20.04.1-Ubuntu SMP Mon
Jan 15 13:09:14 UTC 2024","hostname":"gaetan-Dell-G15"}'
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
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:
- Mon, 12 Feb 2024 23:40:33 GMT
Content-Type:
- application/json
Content-Length:
- '1396'
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-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:
- 2df83cff-6b9e-4b69-a8d6-3a29ae896132
Original-Request:
- req_qlmSU2gDZApvRn
Request-Id:
- req_qlmSU2gDZApvRn
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
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_3Oj96yQQeZbvfZRJ1mJK3wjg",
"object": "payment_intent",
"amount": 1000,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 1000,
"application": "<HIDDEN-STRIPE_CLIENT_ID>",
"application_fee_amount": null,
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg_secret_gYuztzQD3aI900vCqWTwV0Tqa",
"confirmation_method": "automatic",
"created": 1707781232,
"currency": "aud",
"customer": null,
"description": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": "ch_3Oj96yQQeZbvfZRJ1eu9nqj8",
"livemode": false,
"metadata": {},
"next_action": null,
"on_behalf_of": null,
"payment_method": "pm_1Oj96yQQeZbvfZRJ0rDYJTvm",
"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": "succeeded",
"transfer_data": null,
"transfer_group": null
}
recorded_at: Mon, 12 Feb 2024 23:40:33 GMT
- request:
method: get
uri: https://api.stripe.com/v1/payment_methods/pm_card_mastercard
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Stripe/v1 RubyBindings/10.6.0
Authorization:
- Bearer <HIDDEN-STRIPE_INSTANCE_SECRET_KEY>
Content-Type:
- application/x-www-form-urlencoded
X-Stripe-Client-Telemetry:
- '{"last_request_metrics":{"request_id":"req_qlmSU2gDZApvRn","request_duration_ms":1569}}'
Stripe-Version:
- '2023-10-16'
X-Stripe-Client-User-Agent:
- '{"bindings_version":"10.6.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","engine":"ruby","publisher":"stripe","uname":"Linux
version 5.15.0-92-generic (buildd@lcy02-amd64-002) (gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2)
9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #102~20.04.1-Ubuntu SMP Mon
Jan 15 13:09:14 UTC 2024","hostname":"gaetan-Dell-G15"}'
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:
- Mon, 12 Feb 2024 23:40:34 GMT
Content-Type:
- application/json
Content-Length:
- '942'
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-uri https://q.stripe.com/csp-report?p=v1%2Fpayment_methods%2F%3Apayment_method;
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_080Zj6If1DAG4Q
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_1Oj970KuuB1fWySneY4k7dE5",
"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": "mastercard",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "unchecked"
},
"country": "US",
"exp_month": 2,
"exp_year": 2025,
"fingerprint": "BL35fEFVcTTS5wpE",
"funding": "credit",
"generated_from": null,
"last4": "4444",
"networks": {
"available": [
"mastercard"
],
"preferred": null
},
"three_d_secure_usage": {
"supported": true
},
"wallet": null
},
"created": 1707781234,
"customer": null,
"livemode": false,
"metadata": {},
"type": "card"
}
recorded_at: Mon, 12 Feb 2024 23:40:34 GMT
- request:
method: get
uri: https://api.stripe.com/v1/payment_intents/pi_3Oj96yQQeZbvfZRJ1mJK3wjg
body:
encoding: US-ASCII
string: ''
headers:
Authorization:
- Basic c2tfdGVzdF94RmdKUU9sWHBNQUZzb3p0endGQlRGaFAwMEhHN0J1Q0ptOg==
User-Agent:
- Stripe/v1 ActiveMerchantBindings/1.133.0
Stripe-Version:
- '2020-08-27'
X-Stripe-Client-User-Agent:
- '{"bindings_version":"1.133.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","publisher":"active_merchant"}'
X-Stripe-Client-User-Metadata:
- '{"ip":null}'
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
Connection:
- close
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:
- Mon, 12 Feb 2024 23:40:35 GMT
Content-Type:
- application/json
Content-Length:
- '5160'
Connection:
- close
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-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_V4N2hQ53av2Y7Z
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
Stripe-Version:
- '2020-08-27'
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_3Oj96yQQeZbvfZRJ1mJK3wjg",
"object": "payment_intent",
"amount": 1000,
"amount_capturable": 0,
"amount_details": {
"tip": {}
},
"amount_received": 1000,
"application": "<HIDDEN-STRIPE_CLIENT_ID>",
"application_fee_amount": null,
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"charges": {
"object": "list",
"data": [
{
"id": "ch_3Oj96yQQeZbvfZRJ1eu9nqj8",
"object": "charge",
"amount": 1000,
"amount_captured": 1000,
"amount_refunded": 0,
"application": "<HIDDEN-STRIPE_CLIENT_ID>",
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_3Oj96yQQeZbvfZRJ1RsK34U6",
"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": 1707781232,
"currency": "aud",
"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": {},
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 36,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg",
"payment_method": "pm_1Oj96yQQeZbvfZRJ0rDYJTvm",
"payment_method_details": {
"card": {
"amount_authorized": 1000,
"brand": "mastercard",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"exp_month": 2,
"exp_year": 2025,
"extended_authorization": {
"status": "disabled"
},
"fingerprint": "BL35fEFVcTTS5wpE",
"funding": "credit",
"incremental_authorization": {
"status": "unavailable"
},
"installments": null,
"last4": "4444",
"mandate": null,
"multicapture": {
"status": "unavailable"
},
"network": "mastercard",
"network_token": {
"used": false
},
"overcapture": {
"maximum_amount_capturable": 1000,
"status": "unavailable"
},
"three_d_secure": null,
"wallet": null
},
"type": "card"
},
"radar_options": {},
"receipt_email": null,
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xT2haOWxRUWVaYnZmWlJKKPPYqq4GMgbBqrOsaAA6LBbntbfnCS4i_BCTrINWH_iO8IhhvEcUo4NzHmV6T6gBL9XSdNg-1LvMV5fe",
"refunded": false,
"refunds": {
"object": "list",
"data": [],
"has_more": false,
"total_count": 0,
"url": "/v1/charges/ch_3Oj96yQQeZbvfZRJ1eu9nqj8/refunds"
},
"review": null,
"shipping": null,
"source": null,
"source_transfer": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/charges?payment_intent=pi_3Oj96yQQeZbvfZRJ1mJK3wjg"
},
"client_secret": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg_secret_gYuztzQD3aI900vCqWTwV0Tqa",
"confirmation_method": "automatic",
"created": 1707781232,
"currency": "aud",
"customer": null,
"description": null,
"invoice": null,
"last_payment_error": null,
"latest_charge": "ch_3Oj96yQQeZbvfZRJ1eu9nqj8",
"livemode": false,
"metadata": {},
"next_action": null,
"on_behalf_of": null,
"payment_method": "pm_1Oj96yQQeZbvfZRJ0rDYJTvm",
"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": "succeeded",
"transfer_data": null,
"transfer_group": null
}
recorded_at: Mon, 12 Feb 2024 23:40:35 GMT
- request:
method: post
uri: https://api.stripe.com/v1/charges/ch_3Oj96yQQeZbvfZRJ1eu9nqj8/refunds
body:
encoding: UTF-8
string: amount=1000&expand[0]=charge
headers:
Content-Type:
- application/x-www-form-urlencoded
Authorization:
- Basic c2tfdGVzdF94RmdKUU9sWHBNQUZzb3p0endGQlRGaFAwMEhHN0J1Q0ptOg==
User-Agent:
- Stripe/v1 ActiveMerchantBindings/1.133.0
Stripe-Version:
- '2020-08-27'
X-Stripe-Client-User-Agent:
- '{"bindings_version":"1.133.0","lang":"ruby","lang_version":"3.1.4 p223 (2023-03-30)","platform":"x86_64-linux","publisher":"active_merchant"}'
X-Stripe-Client-User-Metadata:
- '{"ip":null}'
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
Connection:
- close
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:
- Mon, 12 Feb 2024 23:40:37 GMT
Content-Type:
- application/json
Content-Length:
- '4536'
Connection:
- close
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-uri https://q.stripe.com/csp-report?p=v1%2Fcharges%2F%3Acharge%2Frefunds;
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:
- 45259ce6-403c-4e58-814e-f5d9a8408b20
Original-Request:
- req_YAl5fRQ21daQPA
Request-Id:
- req_YAl5fRQ21daQPA
Stripe-Account:
- acct_1OhZ9lQQeZbvfZRJ
Stripe-Should-Retry:
- 'false'
Stripe-Version:
- '2020-08-27'
Vary:
- Origin
X-Stripe-Routing-Context-Priority-Tier:
- api-testmode
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
body:
encoding: UTF-8
string: |-
{
"id": "re_3Oj96yQQeZbvfZRJ1g0CJ9FL",
"object": "refund",
"amount": 1000,
"balance_transaction": "txn_3Oj96yQQeZbvfZRJ1jHrLFL1",
"charge": {
"id": "ch_3Oj96yQQeZbvfZRJ1eu9nqj8",
"object": "charge",
"amount": 1000,
"amount_captured": 1000,
"amount_refunded": 1000,
"application": "<HIDDEN-STRIPE_CLIENT_ID>",
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_3Oj96yQQeZbvfZRJ1RsK34U6",
"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": 1707781232,
"currency": "aud",
"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": {},
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 36,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg",
"payment_method": "pm_1Oj96yQQeZbvfZRJ0rDYJTvm",
"payment_method_details": {
"card": {
"amount_authorized": 1000,
"brand": "mastercard",
"checks": {
"address_line1_check": null,
"address_postal_code_check": null,
"cvc_check": "pass"
},
"country": "US",
"exp_month": 2,
"exp_year": 2025,
"extended_authorization": {
"status": "disabled"
},
"fingerprint": "BL35fEFVcTTS5wpE",
"funding": "credit",
"incremental_authorization": {
"status": "unavailable"
},
"installments": null,
"last4": "4444",
"mandate": null,
"multicapture": {
"status": "unavailable"
},
"network": "mastercard",
"network_token": {
"used": false
},
"overcapture": {
"maximum_amount_capturable": 1000,
"status": "unavailable"
},
"three_d_secure": null,
"wallet": null
},
"type": "card"
},
"radar_options": {},
"receipt_email": null,
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xT2haOWxRUWVaYnZmWlJKKPTYqq4GMgZQqAj4ctc6LBbgm76DRSrCQ4pX8VSrXuiayuVxdn1a0v3rX62vwWWKBuWFTGIKRS5Rfctx",
"refunded": true,
"refunds": {
"object": "list",
"data": [
{
"id": "re_3Oj96yQQeZbvfZRJ1g0CJ9FL",
"object": "refund",
"amount": 1000,
"balance_transaction": "txn_3Oj96yQQeZbvfZRJ1jHrLFL1",
"charge": "ch_3Oj96yQQeZbvfZRJ1eu9nqj8",
"created": 1707781236,
"currency": "aud",
"destination_details": {
"card": {
"reference_status": "pending",
"reference_type": "acquirer_reference_number",
"type": "refund"
},
"type": "card"
},
"metadata": {},
"payment_intent": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg",
"reason": null,
"receipt_number": null,
"source_transfer_reversal": null,
"status": "succeeded",
"transfer_reversal": null
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/charges/ch_3Oj96yQQeZbvfZRJ1eu9nqj8/refunds"
},
"review": null,
"shipping": null,
"source": null,
"source_transfer": null,
"statement_descriptor": null,
"statement_descriptor_suffix": null,
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
},
"created": 1707781236,
"currency": "aud",
"destination_details": {
"card": {
"reference_status": "pending",
"reference_type": "acquirer_reference_number",
"type": "refund"
},
"type": "card"
},
"metadata": {},
"payment_intent": "pi_3Oj96yQQeZbvfZRJ1mJK3wjg",
"reason": null,
"receipt_number": null,
"source_transfer_reversal": null,
"status": "succeeded",
"transfer_reversal": null
}
recorded_at: Mon, 12 Feb 2024 23:40:37 GMT
recorded_with: VCR 6.2.0

View File

@@ -134,6 +134,37 @@ describe Spree::Gateway::StripeSCA, type: :model do
end
end
describe "#credit", :vcr, :stripe_version do
# This is the first account retrieved using Stripe::Account.list
let(:stripe_test_account) { "acct_1OhZ9lQQeZbvfZRJ" }
before do
# Inject our test stripe account
stripe_account = create(:stripe_account, stripe_user_id: stripe_test_account)
allow(StripeAccount).to receive(:find_by).and_return(stripe_account)
end
it "refunds the payment" do
# Link the payment intent to our test stripe account, and automatically confirm and capture
# the payment.
payment_intent = Stripe::PaymentIntent.create(
{
amount: 1000, # given in AUD cents
currency: 'aud', # AUD to match order currency
payment_method: 'pm_card_mastercard',
payment_method_types: ['card'],
capture_method: 'automatic',
confirm: true,
},
stripe_account: stripe_test_account
)
response = subject.credit(1000, nil, payment_intent.id, {})
expect(response.success?).to eq true
end
end
describe "#error message", :vcr, :stripe_version do
context "when payment intent state is not in 'requires_capture' state" do
before do