Thursday 15 April 2021

Oracle APEX and Stripe v3 - part 3

  

Oracle APEX 20.x and Stripe v3 integration

Stripe v3 integration Server side - part 3


If you have taken part in this blog series exploring new Stripe APIs we have already seen how to integrate APEX with new Stripe checkout form on a client side. 
 
Today we will look into how the same can be done by using a server side processing where payment will be triggered from APEX PL/SQL over doing it directly in Stripe checkout form we have been redirected to so far. 
 
This post is de-facto an upgraded version of Trent's post we used originally to get Stripe up and running. We will apply the same principles just using latest Stripe APIs and libraries.
 
First difference to my previous two posts is that our APEX apps will not be redirected for a payment to Stipe integrated checkout.
 
Pretty much we will be doing the exact opposite we will build a form in APEX and send it using REST API for processing. 
 
Secondly we will be using amounts instead of Stripe defined products and prices in post 1 and post 2.

Stripe checkout form:

 
will be replaced with APEX built form:
 

Of course this is where the freedom and control come into play for us as developers. 
 
We can build forms as we are used to as in any standard APEX page. 
 
Let's see how. Create a new app page with Blank with Attributes region with this code as a source. 
 
On a page level we will add a reference to Stripe JS
https://js.stripe.com/v3/ 
We need to add CSS that will handle the look and feel of the form and Javascript code that will initiate Stripe payment form for us.
 
Both codes can be found at the link above under CSS and JavaScript sections.
 

What the JS code will do is among other bits and pieces is initialize Stripe card component, create elements on the form and finally attach an event listener using
document.querySelector('.payStripe').addEventListener('click',
Most importantly it will catch the token returned by Stripe which we can use later in our PL/SQL processing to charge the card.
 
If you run the page now you should see the new form with card fields added to it. 
 
Great thing is that Stripe injects everything needed for our form to be able to accept payments. This includes all card validations and processing. Isn't this great!
 
Okay to be fair our job is still not done so we will add few fields to store tokens return by Stripe payments. 
 
Create two new fields  

Now let's make sure we update the JS lines with public key and with your page item name.
//update this line with your ITEM NAME
$s('PX_STRIPE_TOKEN',result.token.id);
Run the page at this stage and click on a Pay button. You should see a token ID returned into PX_STRIPE_TOKEN.

This is the most critical part as without it the next step will not work. Please make sure you get the token back from Stripe.
 
At this stage it does not creates a charge on a card but only 'initializes it'. 
 
The rest of the code is pretty much exactly the same as in an old version of the form checkout. What we will do now is create an on change DA on PX_STRIPE_TOKEN that will execute PL/SQL call:
begin
    stripe_api.set_secret(:STRIPE_SECRET);
    
    :PX_PAYMENT_STATUS :=
        stripe_api.charge_card (
            p_amount => 2500
          , p_source => :PX_STRIPE_TOKEN
          , p_description => 'Charged from a D.A page X at '|| sysdate
        );
end;
Once we got this in, our form becomes fully operational and is able to send payments to Stripe API. 
 
If details are entered and payment is successful we will use another DA to notify the user that transaction was successful.
 

In case you did not get stripe_api.charge_card package so far here is a code for it.
 

How do we check if payment was successful from Stripe side - you can open Payments link in Dashboard 
https://dashboard.stripe.com/test/payments 
also you can check all logs under Developers -> Logs:  
https://dashboard.stripe.com/test/logs
 
Further to this we can easily create a new REST data source in APEX


with simple credentials
 

and then leverage this in interactive report based on REST data source we just created to help us monitor transactions from our applications. ;)
  
I am hoping this will be of help. Lots to take in and read so thank you for sticking with me till the end.

Happy APEXing,
Lino

18 comments:

  1. Great post!.. I'm trying to complete this steps, but I have this error. In this PL/SQL code:
    begin
    stripe_api.set_secret(:STRIPE_SECRET);

    :PX_PAYMENT_STATUS :=
    stripe_api.charge_card (
    p_amount => 2500
    , p_source => :PX_STRIPE_TOKEN
    , p_description => 'Charged from a D.A page X at '|| sysdate
    );
    end;


    ORA-06550: line 2, column 5: PLS-00201: identifier 'STRIPE_API.SET_SECRET' must be declared

    What is wrong?

    ReplyDelete
    Replies
    1. you are missing a PLSQL package stripe_api (but you can call it any way you like). Create one based on code on CodeShare and then it should work.

      Delete
  2. Thanks, now I get this error "Error: The Ajax call returned the server error ORA-06502: PL / SQL: error: string buffer too small numeric or value to Execute PL / SQL Code." when I press pay button. The field STRIKE_TOKEN have been completed and then I get this error. Could you help me?

    ReplyDelete
    Replies
    1. Guessing from here one of your variables is too small. You declared something like varchar2(10) where your value has more characters for example. Without more info I will not be able to say more. Try turning on the debug mode and see what it comes down to.

      Delete
  3. Ok, thanks. It works fine, but I have received an email from stripe indicating that I must implement double authentication factor, something very common in my country.
    https://stripe.com/docs/strong-customer-authentication. Do you know how to solve it? Best regards,

    ReplyDelete
    Replies
    1. Unfortunately I do not have examples ready for this at this stage. If you read documentation "Accept card payments with the Payment Intents API and Stripe’s new version of Checkout—a prebuilt, Stripe-hosted checkout flow that automatically handles SCA requirements for you. Checkout is customizable and lets you accept payments for one-time purchases and subscriptions on your website." for one of the "more secure ways" should already be working for you if you check out my demo on built in Stripe checkout form as far as I understand it. :)

      Delete
  4. Hi there,

    I have tried this excellent example, thanks for sharing.

    however I am getting this error although i have provided the api-key and also tried to hard-code it in the procedure.


    Body: {
    "error": {
    "code": "secret_key_required",
    "doc_url": "https://stripe.com/docs/error-codes/secret-key-required",
    "message": "This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys.",
    "type": "invalid_request_error"
    }
    }

    ReplyDelete
    Replies
    1. From what I can say from here you have mixed private and public key. Otherwise I would have to have more details to say anything more than this. Lots of people tried these and for most this has worked so.....

      Delete
    2. Hi Slino,

      Populating the :STRIPE_SECRET was not clear to me, initially i thought it was getting the value from the api...

      I added the private key and it worked just fine as you description. Thanks once again for your blog.

      Now i am trying the payrexx api, that seems to be somewhat more challenging and less intiutive.


      Delete
  5. Sir can you make a video on this please, it will be helpful for us better understanding.

    ReplyDelete
    Replies
    1. Unfortunately I haven't planned on doing a video on this. It has to do with finding time to do this.

      Delete
  6. Hi You mentioned ..

    Let's see how. Create a new app page with Blank with Attributes region with this code as a source.
    But when i click on code i dont see anycode. .Thanks

    ReplyDelete
    Replies
    1. Wonderful, someone actually managed to delete the original code from my codeshare. Let me have a look if I can find it again.

      Delete
    2. There code should be back to its place

      Delete
  7. Please people let's try not deleting the code shared with you :D

    ReplyDelete
    Replies
    1. Excellent article and blog. I've sent a number of people your direction.

      Question on the page code -- clicking the link (https://codeshare.io/GLQ4vb) I'm seeing the inline css and js, but it sounded from the blog post that the form elements were also a part of that file to be pasted into the source of the region. That doesn't appear to be there now. Maybe I misunderstood, or maybe someone got happy with their cut/paste - again. Figured I'd ask!

      Delete
    2. No, I believe all needed code is still there. I added a form code for the reference. Thanks for letting me know.

      Delete
    3. Works like a charm and am taking in payments! Thanks!! Working now on getting Payment Elements (launched Fall 2021 at Stripe) working in another part of the software. That's quite a bit different, but great if it works as it takes in multiple payment types.

      Delete