I could really use some help here... after about a week of trial and error I'm still stuck -- hoping someone can help me finally get this right :)
I need to have visitors pay via Stripe -- they complete name + credit card fields (note: I have this code for this working, but only when I don't have other functions connected to its submit button, because this takes longer.. thus async/await)
THEN, when they click "submit" I need 1) Stripe to process, then 2) "name" field is saved to a database where I can cross-reference if a user has paid for a membership yet or not, then 3) redirect to "Success" page
I've tried many different ways, but can either only process Stripe or submit to the DB, but I need both, and in that order. This code seems to get me the closest to what I need. I just need to figure out the async/await bits...
I'm really new to this, and I'm piecing it all together from what's worked and what hasn't, but I think I need something like let ___ = await payNow(); around line 6, just not sure what goes there...
Any input is welcome, since I'm about ready to slam my head into the wall, and I really need to get this off to the client. Thanks in advance!!
Noway, I followed all and I didn't find the good end.
Annie did you solved and how ?
Thanks in advance
Mauro
Thanks again! Still stuck, though :(
Below is my most recent attempt, using your notes...maybe I'm just missing something small still? The token is going through, and member is inserting into DB, but ID is coming back from Stripe 'undefined'.
I'm sorry to keep bugging you with this, but I'm just struggling to wrap my head around all this and figure out the issue. Any thoughts, Giedrius?
Here's the backend code too, in case something's off there now. Note there is an error on line 28 ('entries' is undefined for "Object' in ecma5) .. I don't know if this is related...
Thanks again for all your help!!
It this case it might be more convenient to make payNow() async and reorganise it as:
async function payNow() { const token = await createToken(encodeCard(createCard())); console.log('Token: ', token); const chargeResponse = await charge(token); console.log('Charge ID: ', chargeResponse.id; }
The code is equivalent, but it is easier to track of what needs to be passed where. When inside of async function, you can always refactor this
asyncFunction().then(result => process(result))
to this
const result = await asyncFunction(); process(result);
I hope this helps! Let me know.
You also need to add return before the charge method. If createToken(...).then(...) block is not returning the promise from charge() method, it will not be awaited on.
So, as current code stands, await gets completed promise as soon as createToken(...).then(...) block is executed. And although charge is called, its promise does not get passed from the createToken(...).then(...) to be waited on.
So close! Now Stripe seems to be sending, but not receiving.. I'm getting the charge token, but no charge id
I also tried export async function payNow() and it made no difference
Oh, I've noticed you do not have return in your payNow() code. It should be
return createToken(...)...
Otherwise, you are not returning a Promise from payNow() method. So await effectively does nothing and just proceeds to next step. wixLocation.to('...') will break the pending payment code by going to a different page.
I hope this helps. Let me know!
P.S. It is really important to mark payments as completed in backend and make PaidMembers collection accessible only to Admin. Otherwise, anyone can insert the record there and become a "paid member". In the backend code you can do insert with admin rights by specifying suppressAuth parameter.
wixData.insert('PaidMembers', { title: ... }, { suppressAuth: true })
Thanks again Giedruis .. I'm just confused, because if I remove the additional sections of code that refer to the insert or redirect then the Stripe code works fine
Hi Annie,
from async/await standpoint, your code is fine. It should be something like:
await payNow() await wixData.insert(...) wixLocation.to("/success")
My guess that there is an issue with Stripe payment code.
Furthermore, I'm not sure about the flow of your site, but inserting paid member from frontend looks like a risky move. This should be safely done in backend code by checking if the payment was actually accepted.
Hi again gurus!
I'm still stuck :( I understand the "big picture" but for some reason am just having trouble figuring out like connecting these pieces and the details. Can anybody help me make this work? I really need to get this site finished for my client ASAP -- I've been at it for 8 days now I think.
I've given it several more attempts since the last post(s) but no luck. I can't figure out how to:
- Click submit, then
- Submit $ to Stripe, then
- Insert name from form field into Paid Member database, then
- Redirect to Success page
I'm currently only editing this one section of code, so if I should also be looking at the rest (lines 1-3, or 15 on) please let me know!
Here's some stuff I've tried.. hopefully I'm close with one of them!
'paymentResults' unread error:
This does't process Stripe, just inserts into the DB and redirects:
This one doesn't use the onReady -- not sure now if that's good or bad -- but again, it doesn't process Stripe, just inserts into the DB and redirects:
I'd really REALLY appreciate anyone's help! Thanks in advance!
Thank you Giedruis! So I think that makes sense.. This is probably a dumb question, but I'm just so lost now. Would I simply make a change like this?
What do I do with paymentResult elsewhere to make this work? Does all the other code after that stay as-is or would I edit it as well?
Hi Annie,
you are actually right on with the required solution.
Technically: Every asynchronous operation that returns a Promise can be 'awaited'.
Your payNow function looks like it returns a Promise (because you also wait for it with .then({execute things here after operation completes}). Wix Data operations also return promises. So, if you wanted to make it super simple with async/await you could do something like:
function doEverything() { const paymentResult = await payNow(); await wixData.insert(...); wixLocation.to('/'); }
I hope this helps!