Adalo Preauthorized stripe Payment
DISCLAIMER: While this content has been left online for learning purposes, Ops machine specifically recommends NOT using Adalo, ad it's been shown to be frighteningly insecure, incomplete, and generally near impossible to deliver with, in the time that we used it.
Further, the Pragmaflow component library is no longer maintained after having been broken repeatedly by adalo platform updates.
In this tutorial we go over how to integrate compliant preauthorized stripe payments into you app using stripe.
https://stripe.com/docs/payments/checkout
Link to the full PragmaFlow Adalo component toolkithttps://adalo.pragmaflowservers.com/install-component
Sign up with make.com here (affiliate link):https://www.make.com/en/register?pc=pragmaflow
Part One Transcript
Now the app here is called money, pickle, and the point to the app. Is that anyone can go and speak to a financial professional for a dollar 50 a minute, and we don't have to pay some of the higher fees that are typically associated with it. You don't necessarily need the a hundred K that it takes to speak to one of these people.
So in this case what we wanted to do was preauthorized before the call and then based on the amount of time that the call takes, we want to charge the. Now, if you've worked with these kind of things before then, you know, it's not really easy to do. How did we do it? It , it was a little complex, but maybe not too crazy now that we've solved it and hopefully this can be helpful to you.
So the component that we used there are a couple actually, no, you know, the the really important one here is our web view. And outside of that, it's all standard download components. Now this is our web view. The Pragma flow better web view, I suppose, is the nickname. And the reason it's better.
Is because it can actually detect the URL of the page that you are on and then take actions based on that. So we can automate web flow, web flow. We can automate web view experiences as part of the app. And we can respond to what's happening in the web view, which creates a really integrated experience and kind of complete some of the workflows that are hard to solve when the Addo app itself cannot understand what's happening in the web.
Okay. So how does it. If you take a look on this page, we have a hidden countdown, hidden countdowns are really useful for doing page actions where we're using a custom action. There is a known bug in Adela, and I hope one of you will tell me that I'm just a dinosaur that's been fixed, but the bug was that if you used a custom action and you return information or data, then you cannot use that data in the next actions.
That custom action was a page action. Meaning if it is when you land on the page, an action that fires. So what we do to work around that is create a countdown 0.1 second. I think you can do zero, but something, I don't know, just, I guess it's after the page loads or the component just, it feels like a better idea.
So what's happening in here? All right. There are a few things. So first we are creating the checkout in. And, you know, I realize I actually am gonna have to back up, but let's talk through this and you'll understand why I'm gonna zoom out. So we have the OWO call record ID. This is the ID of the record in the OWO database, so that when we do our action, which is gonna happen in make.com.
And then afterwards, we want to update the record. We're going to know which record to. So we'll talk more about that in a second. So we're sending the current Al record. We are sending the user's email and we're sending their name. So what's happening when we do that. Okay. So if we take a look, this is the Stripe instance generator.
Now, why do we even need to generate an instance? What's all this about. on the next screen over here what's gonna happen is in this web view, we're going to load up a Stripe checkout. And so by using the web view, we are never actually in the Al app, the client is never putting their information into the Addow app.
What's happening is they're giving it to Stripe directly through stripes checkout process. But that is not a static page. There's not just, Hey Stripe, let me go to your checkout page. In fact, you have to say, Hey, Stripe, make a checkout page for this user for this reason so they can check out. And that makes sense, because we want security.
We don't just want people showing up at the, you know, and doing whatever they want and being able to modify. So we start with the custom web hook and you can see in some of our past videos, how to just do the basics of setting up a custom action with a web hook. Now this web hook is here. Let's take a look.
I want to show you, well, this is the data actually, that it's expecting what I showed you here before the Adela record ID, the user's email and the user's full name. So we go through here now. We have some filters and let's see why , I've kind of forgotten how we set this up. Perfect. Okay. So we have a thing on there called request type.
And if it's empty as if it's empty. No. If it contains create. And so let's just take a look at where that's coming from. When we go into our custom action over here, we can see that we have request type also, and this is hard to coded. The reason it's hard to coded is because this request is always going to be.
So we go along this route and what happens, we create a customer, so we need to create a Stripe customer so that they know, you know, some information about the person. So all we need to provide is the email and name. And then when we go over here, we request intent checkout instance. So what is an intent checkout instance?
An intent is essentially one of the ways that Stripe does preauthorization. So we're declaring an intent for the client to. In the future. And so we use the V1 slash checkout slash sessions, and you can check out the Stripe API documentation for more there. And then we have to send these keys, the payment method type, which in this case is card.
The mode is set up and set up is because we're setting up an intent. The customer, we have customer ID here, which we got from the creative customer. That's the value that was returned. And you can see when I mouse over it, the number 10, it's a little hard to see, create a customer is kind of pulsing happily there, which is a nice UI effect and then success URL.
So where are we going to go? If things are successful, we have this URL right here and that actually is, I believe this web hook as well. Now, the other thing is request type equals success. We'll talk about what's gonna happen there in just a second. And then we have the cancel URL and that's, if there is not a.
So we're going to redirect to two different URLs and they're both this web hook, but the only difference is the parameter which you can see after the question mark here, the parameter request type equals failed or equals success. So again, we'll come back to that finally, with the response that we've gotten here, which will include the instance ID.
What we are doing is first of all, we have a pre-op ID. So if the status code is 200, meaning if they're. Then we're taking the body setup intent, which is again, returned, as you can see from the previous step. All right. Next we have pre-auth instance created. So this is, again, something that we're using you know what, let's, let's flip back to what happens next, cuz I don't think this has great context yet.
So when we when we get our response, right. And it is going to update the Addo record. So what's gonna happen is after this action runs, we're going to take one of two two follow up actions. We're either gonna link to pre-op to, which is the page where we're gonna show the checkout instance.
Now that we have the ID or we're going to link to pre-op error. If we found that there was an error. Okay. So how are we determining this? The way we're determining. Is sometimes. So I had to find a good way to do this with the constraints that Addo offers. I like to avoid the possibility of something actually falling in two categories, or maybe a response that falls in neither, cuz then we'll jam.
We need to, we need to cover all the range of possibilities. So I decided to use a numerical code because that's anyways, how we often send the response. And so what that means is if the checkout response is between 202 90, We're calling that a success. Sometimes it returns 2 0 1 S I wanna say. So I decided to account for the whole range.
Now, if we hit a 3 0 1, that's a redirect. I don't think I wanna mess with that. I think we're gonna call that an error. So being a bit conservative. And so here we go. If, oh yeah, actually funny story. So maybe I'll fix this to greater than 300. So we haven't gotten 300 yet, but I did leave a range where nothing would happen and, and that would be weird.
So now it's fixed. So if it's a redirect or a 400 or 500, which are authorization or server errors, then we're just gonna go to the pre-op error screen. Okay. So how do we send that response back? That's what we're doing here. So if we have the status code equals 200, because it is essentially. I probably could also mirror on this side the same conditions and it would probably be wise to, I haven't hit an error yet, so I'm gonna just leave it for the sake of the fluid dity of the tutorial.
But we could say if status code is between instead of equals, but if it equals 200, we send back the intent to Adela. If then we have to say is the pre-op instance created and we're using this just to understand on the call, can we advance the user? Do they have a pre-op instance? This is our tracking.
So again if it is, if this is true, then we are sending the oh, yeah, sorry. So if this is successful, we're sending true. If not false, by the way, here, we're sending nothing. If it is. You can just see if you mouse over the, if, how this works and when you're in make, you can easily see that. So the current pre-auth URL so if this is not 200, then we say failed.
If it is 200, then it is again, the body URL coming from the last instance, and this URL is what we will plug in to the web view. All right. Finally, the Stripe customer ID, which we're gonna return we aren't gonna store customer credentials. But the customer ID itself is something that's useful to invoke later.
All right. So that is the first half. And at the end of it, we're going to return the URL and response code. And so basically here we go. This is the response to the actual web. So, this is what Adal is gonna see as a response. So at the end of this flow whatever's happened unless it went along this fad request route it's going to receive URL, which is the URL, and it's going to receive response status code.
Now, I think there's a bit of redundancy here at this point, cuz you're seeing us having worked through a couple of iterations of how to do this and it probably needs a prudent. So I don't believe that is still useful, but what's really cool is you can use Webhooks for make.com to directly respond.
Two, the actual so you can control what is returned to the custom action in Adel because the fields that show up are the fields that are here. So when I run this and do my test, I'll see URL in response at the end. Okay. So what we will do, I think is pause here and come back to a part two video on how to finish this up.
Part two Transcript
All right. What up everyone? We're back for video two on how to create a preauthorization Stripe instance in a dial that will not require your app to BPCI compliant, because we work around the whole issue. So let's. Let's pick it back up at the end of the last one. We've done this here. Custom action on our first page to create the checkout instance, by the way, this here is just a loading animation, because it does take a few seconds and it's nice to let the user know that the app hasn't jammed.
All right. So after we create the instance using make.com and using Custom action. And we direct the user based on the result we end up on the actual pre off screen. And so what we have here is a web view and really straightforward. What it's going to do is it's going to show URL and it's taking the URL that was returned from the last section.
And the way it's getting that again is it's coming through this make hello and we're just plugging it in. So when we ask for the it's called the setup intent, right? The, the intent or the pre off screen, so that we can take the credit card info in, charge it later, we're gonna get a URL. That URL is gonna be somewhat.
And we present that to the client. We send them to that screen. so they can then put in their information and strike will grab it. And it never actually sits in a download's database. So that's really useful now. If we take a look at what's actually happening here, we're doing some conditional actions, right?
So in the last let's just take a look back here in the last section. What we were doing is when we requested the intent, we also specified where we're gonna re. Actually, this is the web hook address for over here. So when a user is done their checkout, they are going to basically get redirected to a screen that actually goes to this URL.
Now what's happening here is the second they get to that screen. We're gonna redirect them. So they'd never really see it right here is. So first thing we're gonna do is we're gonna update the current. And we're gonna say that, what do we do here? Huh? Are we not changing anything? That's funny. We might be able to remove this.
Yeah. Okay. So I guess I'll prune that after. So ignoring that guy. So what we're doing is we are linking based on the result, which makes more sense. I was wondering what we were updating there. So we're going to, based on if this link URL contains success. So the way we're doing that link URL comes from web view component URL.
So every time the screen changes, this component will detect the URL and then it'll check the URL against this condition. So if at any point the link URL contains success. We're going to link to the call now or schedule. Okay. So that's the next page. And I just use it as a routing page. When you land on it, it sends you one way or another based on if you scheduled a call or if you want to just do a call live right now, the other.
So just take a look back in here is pre off error. Right? So if there was an error, if the link contains fail. So once again, that is specified in our setup, we are sending them either to a link where one of the parameters oh yeah. Wrong one. So we are sending them to link where one of the parameters contains success or otherwise contains fail.
Now I think most of you looking at this probably recognize this format. This is a parameter, right? Or a query. And I think they call 'em parameters too. Basically when you're setting up your custom action, this is the same thing. And if we wanted to add another one, we'd add an Amper send and then a second equals value.
And we could do that. I just won't cuz we don't. all right. So that is how we actually take the payment. Now, what I wanna do is loop back on something important, and I apologize for the like kind of splitting this idea across two video. Over here. I am actually specifying. So what we're doing is we're getting the information, right?
We're, we're getting the, creating the client. We're getting the intent. We could, by the way, try to look for the client first, which would be a nice addition. So we don't create a new one each time, but it's not a big deal. And so based on this, we're actually updating the Dialo record. Now at the top, you'll notice that I have the, a Dialo call record.
I. And that means that I know which record I'm updating. Now, if I pause for a second, for most, that's really hard to do in a dial, because for some reason they've obscured the crap outta their record. I. And so it's really, really hard. And the, the horrific thing that we usually have to do is get all of the records, then filter for the one that matches the email of the user, or finds some, like, create our own idea and match for it.
And, and that whole thing sucks. Not only cuz the performance is terrible and not only cuz asking for all the records in a collection, it's just a ridiculous thing to do. Not just, yeah, so it's whatever I could spend 20 minutes just saying how bad it is. So we, we never wanna. And so one day when I was faced with that, I was talking to Steve.
I said, Steve, can you please just make me a component that gets the record ID? And so we've had that for a while and it's pretty nifty the Addo record ID button. And so how does that work now? The thing is Steve made this in a way that actually works really well, but it also is very constraining and the way, I mean, that is like, you really have to think, how do I get this thing into my workflow?
Right. The options are limited. So I have like, you can't even really change the font eyes yet. I had to put this rectangle behind it and whatever, but, but the reality is it's still pretty great. So here's what I do. I filter based on the criteria of the record, I'm trying to find like any list. So I want one of the logged in users calls, right?
Cause I'm getting the current user's call the one that they're, I'm basically loading current call. And so, and I, I don't think I can get this from a parent list, but maybe that would be a way to do it either. What we have here is pre-auth required is true. So that's my criteria. You don't necessarily have to know why this is what gets me to the current call, but it does.
So when I have that current call and I click the button, I can, you know, it's a button like any other, so I can do whatever I want when I click it. So one of the things as I link to the next page and the other is I update the current call. And the update that I make is I've created a field called Adela record ID.
And so basically just to explain the flow a little bit at large, when you land on this page, it creates a new call for you, assuming that you assuming basically that you don't already have a call object, that's active. And I gauge that using the field that I just mentioned a second ago, which is the the pre-auth required.
Cause if you've already preauthorized it, then. Then we either have to start the flow again, or you already used it for a call again, that may not make sense. So just bearing with me here, the important thing is that when we have the condition where I know it's a new call and I need to add a number to it so that I can identify it in the future.
By setting this button to filter for it and clicking on the button. I can go and update the AALA record ID. I think I said this in way too many words. So thanks for bearing with me. I hope you're watching this on double speed. how do we do this? So we you know, plug in magic text, like anything else. We use button with record ID, we choose record ID and that's it.
So now when I get to make.com, I actually know my record ID and that makes my life so much easier. I'm going to pause here. And then what we'll do is come back to we'll come back to part three where I'm gonna show you how we retrieve the intent. And hopefully I know what I'm talking about, cuz actually Phil made this.
So maybe we will pull him up if I can't walk through it. Thank you for watching, like and subscribe, et cetera. Stay tuned for part three.
Part Three Transcript
All right, everyone. Welcome back to part three. So let's round this thing out. Now, we were working on the money pickle app. We worked our way through the first two sections. Quick recap. We created a setup or pre-op intent instance so that we could send our user to it. We sent our user to. We did all sorts of you know, asking for the intent, updating the record, figuring out if it worked all the kind of integration that makes it make sense in the Al app.
So those were parts one and two, we talked in part two about how to find the record ID, so that. We know what record to update instead of asking for all of them and filtering, which I'll say it again is just horrendous. So never, never do that. Never do that. And you can find the record button ID component on our site.
I didn't mention that in the last video put in the comments. So now we have the preauthorization, we have everything we need. The client has gone through their call. We know that the client spend 20 minutes on the call, let's say, and now we need to build them for that. So how do we go back and do it? Okay.
So basically we just fire a custom action when the call is done. Let's let's see if we can find that screen real quick. Yeah, here it is. We're using the garlic IO video call component. Shout out to them. It is pretty good, actually does its job very well. So that is nice. And then we have hang up.
Action. So the one thing is that it's a little challenging to do actions based on who hangs. No, you know what I'm saying? That out loud, that's silly. I can solve my way around it. So all in all great component and one of the things we do is we we use integr make so when we end the call, we basically use, make to process the payment.
So that's how it's triggered. Let's see, what do we send over? Start time, end time. So we know the amount, although time date times from a Dialo are sent in this really weird format. It's. Unix epoch format, but it's based on days, not seconds. So you have to convert it. It's really irritating. So sometimes it's easier to just do the math here.
So we send the user email, the name, the setup, intent ID, watch video, one to learn about that. We send the customer ID again in video one, we send the Adela call record ID, cuz we want to update the call. So I just mentioned it, but that's in video two, we calculate the call cost here and. I wonder if this is gonna work, cuz we do cost for duration.
So may have to check that that's not broken. I made a modification here recently to fix it. So let's see. But that's the information we're sending. So what happens on this side is we have the web hook where we receive it now is called duration more than 10 minutes. Cause if it's not it's free, so we just kind of end it there.
We, you know, pass through this filter, then we are going to make a Stripe API call. We are making a call to the V1 setup, intense slash the idea of the setup intent that we are trying to retrieve. We get it. And that looks like about it. And so that's gonna return information and we're going to create a payment intent rather than just setting it up, which we've done in the past.
So we do our math for call cost. We specify our currency recipient email. For payment types. Oh, we got to leave this empty cool customer ID, which you've seen in video one again, and it's actually returned from the previous step anyways. So arguably we don't need this into Dialo at all. And if we don't, we may as well go and remove it after choose an existing payment method payment method ID.
Right? So again, from the payment intent, we have all this information. We don't need to remap it and So now we need to confirm the payment intent. And we can do that because we have all the information about the client and the intent. And so we give the payment intent ID. We give the piece of information we got from number 10.
And yeah. So we go and yeah, that's it pretty much. Oh yeah. Right. Cuz once you confirm, confirm is, is like a way to say, you know, We're taking it. So here we go. We've confirm and capture. I have to admit at this point that actually I'll update in the comments, the nuance difference between confirm and capture because I actually forget what they.
But here are the two steps that Phil had to do. So without being able to explain them thoroughly, but I'm pretty sure if I paused, looked at the documentation and came back it would be pretty easy to explain. So again, confirm we use the payment intent ID, we use the payment method and then to capture it, we use the payment intent ID and the amount.
And then we. So that is it, it is pretty simple once it's been figured out. I mean, there's a lot of complexity and, and frankly, the first video might have jumped around a bit. So you know, but thank you for bearing with us. This is in the end, how you can use a Dialo and make.com to create a. I don't even wanna call it PCI compliance, cause it's not relevant in the sense a like PCI compliance, irrelevant, or it, you know, something that's entirely in Stripe system that you do not need to take the responsibility for.
And therefore we don't need to worry about a download's you know, any, any of the behavior or the security or compliance on that side. Now another thing you'll notice is again, just to be sure, like we've never sent credit card information. From Adal to make.com. All of that happens between make and Stripe.
We've never put anything like that. That's private directly into Adal and that's the goal. And it's all going through our web view through strip's checkout. And so, so that's, it, it's all beautifully. We're using the things that are already made. We're not rebuilding anything ourselves. So again, I hope this was useful if it was like, and subscribe, we'll be coming up with more videos and we'll certainly be putting out videos about our up and coming low code.
Code named FIA at this point, designed to be the low code builder that will take you from. The junior level, all the way up to developer level and you know, hopefully through progressive abilities and, and kind of pulling away the guardrails as you grow, make it a platform that really everyone loves.
It's gonna be open source. It is free to use. We will be offering hosting. It should be a, a really awesome, awesome experience. And we're looking forward to launching the earliest earliest aversions where it's still gonna be horrible, but , it's gonna get better very quickly. So, so keep tune for that.
And yeah, I guess if you're interested, subscribe, and you'll hear more about that project as well. Oh, thank you so much for watching again. This is Mitch and I'll see you soon.