There doesn't seem to be a way to test a failed transaction.

eat_to_evolve
Excursionist
18 0 9

If we are using Shopify Payments in test mode, it doesn't allow you to put in an invalid credit card number from https://help.shopify.com/en/manual/payments/shopify-payments/testing-shopify-payments#simulate-faile.... When you try to checkout, it fails. If you try to update your payment method to one of those, it just says 'Failed to update payment method'.  So this means the payment method on a subscription is always valid in test mode, since we can't add non valid ones.

any ideas?

Replies 11 (11)

simplee_chris
Shopify Partner
55 3 14

I agree, this is very important to test our failed credit card flows. Would revoking a customer's payment method lead to a failed billing attempt?

There needs to be a way to add an invalid credit card number or to invalidate a credit card using test mode.

matart
Shopify Staff (Retired)
31 4 5

Hey  chris_mctavish!

 

I believe revoking a customer payment method will give you an error code but it won't be the same as if a card was declined, or another error. 

 

Here is a current list of error codes that can be returned: https://shopify.dev/docs/admin-api/graphql/reference/orders/subscriptionbillingattempterrorcode 

To learn more visit the Shopify Help Center or the Community Blog.

eat_to_evolve
Excursionist
18 0 9

Hey @matart , I understand we can look at the error code, but the issue is I cannot actually make sure a transaction fails so I can test my flow properly with retries. Is there any plans to allow us to enter invalid card numbers?

matart
Shopify Staff (Retired)
31 4 5

Hey @eat_to_evolve!

I wish I had better news, this issue is on our radar but there currently isn't a timeline for implementing it.

To learn more visit the Shopify Help Center or the Community Blog.

matart
Shopify Staff (Retired)
31 4 5

Hey eat_to_evolve!

Currently there isn't a way to test a card that succeeds initially and then fails for the reasons that you mentioned. The best way right now is to look at the error code[1] that will be returned when a billing attempt fails.

 

References:

1. https://shopify.dev/docs/admin-api/graphql/reference/orders/subscriptionbillingattempterrorcode

To learn more visit the Shopify Help Center or the Community Blog.

ChrisF2132
Shopify Partner
2 0 0

I ended up finding a way to make this work by checking out a subscription with the normal test card, and then using the sendCustomerPaymentMethodUpdateEmail mutation to receive and email to update my card.

 

I then updated the customer's payment method to Stripe's "Decline after attaching" card:

4000 0000 0000 0341

(https://stripe.com/docs/testing#declined-payments)

And then tried to create a billing attempt. It then fired the "billingAttemptFailed" webhook and I was able to test my flow.

I also tried getting the update payment url and revoking the payment method via mutations both threw me respective errors:

Payment method instrument not supported for this mutation
Failed to delete customer payment method due to presence of valid subscription.

devsmk
Shopify Partner
7 0 3

So the method mentioned by @ChrisF2132 may have worked in the past, but as of July 2022, it just approved all transactions, defeating the purpose. The only way that I’ve found to make it work, while awkward and clunky, but gets the desired result is listed below. And I know it’s been a while since this question was asked, but Shopify still doesn’t think it’s important to be able to test our apps, you know, like apps that are responsible for charging customers real money. Who needs testing, Nah! Your code looks good enough.😑

 

I found this about a year later so I’m sure others will be able to use this method as well going forward.


1. Checkout in Test Mode with a card that gets successfully charged.

2. Disable Test Mode in settings (I’m using the Shopify payment gateway as I believe it’s required to test subscription apps).

3. Then trigger the sendCustomerPaymentMethodUpdateEmail mutation and update the card to a real CC number (I just used my bank’s Debit Card. And because we are no longer in Test Mode, it will allow this change to occur). 

4. Go back into your development stores settings and re-enable Test Mode. This is super important so you do not charge your own card. You could always refund, but it’s best to not have to. 
5. Have your app perform a billing attempt on the customer who you just updated the card for. My internal logic queries my dB and looks for any entities with their nextBillingDate set to today, and pulls their subscription contract Id into the 

subscriptionBillingAttemptCreate mutation.
6. This should run the billing attempt against the real card for that user and spit back an error_code of payment_method_incompatible_with_gateway_config and an error_message of Payment method cannot be used with the current payment gateway test mode configuration triggering a subscription_billing_attempts_failure webhook.
 
Voilà!
 
**NOTE**
Use your own card at your own risk. This is not financial advise 🤫. Please, for the love of all that is right, remove your real card after you’re finished testing and put back one of Shopify’s spoof cards. Or, just in case someone from Shopify sees this, just add a test card that is able to be added, but fails on billing attempts, like Stripe does. Then this whole thing would go away. Thanks!
kunalwf
Shopify Partner
28 0 4

Wow you're a god

ChrisF2132
Shopify Partner
2 0 0

The way I described above still works in May of 2023!

alex1997
Shopify Partner
4 0 0

 

In order to test without using a real credit card, I've found a workaround using Stripe in Test mode throughout the process.

Firstly, I initiate the subscription as usual, employing a test VISA credit card number (4242.4242.4242.4242) as outlined in the documentation.

Then, prior to triggering the subscriptionBillingAttemptCreate, I navigate to the customer's page. Here, I manually update their payment method through the 'Replace card' process. Choosing a card that simulates successful transactions, I select a card type not accepted by my Stripe setup. For example, I choose a Diners Club card number (3056.9309.0259.04) for replacement.

Finally, when I execute the subscriptionBillingAttemptCreate, it successfully triggers the webhook SUBSCRIPTION_BILLING_ATTEMPTS_FAILURE, allowing me to test a failed transaction scenario without the need for a real card.

thanh_mohc
Shopify Partner
3 0 0

I've tried @ChrisF2132 's method and can confirm it is no longer working as of now (27 Jan 2023). I am not comfortable with using my own credit card like @devsmk suggested. I finally figured out a way:
- Check out a subscription product using a Stripe test card, remember what type of card you are using for this checkout, ie. is it a Mastercard or Visa or Amex, etc.
- Then go onto Stripe Admin -> Settings (bottom left) -> Payments -> disable the type of card you used earlier -> Save.
- Configure a something to listen to the Webhook of type SUBSCRIPTION_BILLING_ATTEMPTS_FAILURE
- Then trigger a billingAttempt from your app, you should see a Failed billing attempt comes through. I used Google pub/sub, my webhook payload look like below:

 

{
"id": 454765668,
  "admin_graphql_api_id": "gid://shopify/SubscriptionBillingAttempt/111823452346",
  "idempotency_key": "whatever-unique-key",
  "order_id": null,
  "admin_graphql_api_order_id": null,
  "subscription_contract_id":2353425623,
  "admin_graphql_api_subscription_contract_id": "gid://shopify/SubscriptionContract/2353425623",
  "ready": true,
  "error_message": "Credit card brand is not accepted for payment",
  "error_code": "unexpected_error"
}
This is a full list of error codes for a billingAttempt https://shopify.dev/api/admin-graphql/2023-01/enums/subscriptionbillingattempterrorcode , maybe you can simulate more scenarios such as Invalid Address,  PAYMENT_METHOD_INCOMPATIBLE_WITH_GATEWAY_CONFIG, etc.

 

I hope that helps.