Last active
August 31, 2021 17:22
-
-
Save d1manson/7ac82e100add42e747dcbea72c1100cd to your computer and use it in GitHub Desktop.
for use in testing stripe intents server side. note this is for use with a test mode key. relies on implementation details that might change
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { STRIPE_PUBLIC_KEY } = process.env, | |
axios = require("axios"), | |
qs = require("querystring").stringify, | |
{ JSDOM } = require("jsdom"); | |
module.exports.simulateAction = async function( | |
intentId, | |
clientSecret, | |
mode = "setup_intent" | |
) { | |
// These are all the bits we have to gather as we go along | |
const data = { | |
url1: null, | |
url2: null, | |
url3: null, | |
url4: null | |
}; | |
if (mode === "setup_intent") { | |
data.url1 = `https://api.stripe.com/v1/setup_intents/${intentId}`; | |
} else { | |
data.url1 = `https://api.stripe.com/v1/payment_intents/${intentId}`; | |
} | |
try { | |
const res1 = await axios({ | |
url: data.url1, | |
method: "GET", | |
params: { | |
is_stripe_sdk: false, | |
key: STRIPE_PUBLIC_KEY, | |
client_secret: clientSecret | |
} | |
}); | |
data.url2 = res1.data.next_action.use_stripe_sdk.stripe_js; | |
const res2 = await axios({ | |
url: data.url2 | |
}); | |
const doc2 = new JSDOM(res2.data); | |
data.url3 = doc2.window.document.querySelector(`input[name='return_url']`).value; | |
const res3 = await axios({ | |
url: data.url3, | |
method: "POST" | |
}); | |
const doc3 = new JSDOM(res3.data); | |
data.url4 = doc3.window.document.querySelector("form").action; | |
await axios({ | |
url: data.url4, | |
method: "POST", | |
data: qs({ PaRes: "success" }) | |
}); | |
} catch (err) { | |
console.dir(err); | |
throw new Error("simulateAction failed"); | |
} | |
}; |
This broke in late Aug 2021, had to remove a bit of the logic for going from step 3 to 4. should work again
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Annoyingly Stripe don't provide a way to simulate a user doing the "requires action" step in 3DSecure - the only option is to follow the flow in the browser as though an actual user was doing it.
Here, we do follow the flow, but in the style of scraping rather than being a proper (headless or otherwise) browser.
If this stops working, it's worth checking if Stripe have updated their api to offer an easy way to do this. You could also check if anyone else has published another utility that does this.
If you do decide you have to get your hands dirty and fix it, it may not be that hard. The main thing is to run through the flow in Chrome with the network tab open. and look for all the "interesting" requests to stripe's domain. Use Chrome's copy as curl thing on the right-click menu of the relevant requests.
To get comparable curl requests from this code you can run:
And then after requiring axios in the code, do:
I ended up using Chrome with incognito mode - I'm not sure if it made a difference, but it seems that there weren't any relevant cookies. In fact I didn't find any relevant headers at all in the end.
The main thing is to be very precise when comparing the curl requests in chrome and the curl requests from axios here, otherwise you will end up going around in circles!