Help needed with syntax for repeating within js - PayPal Checkout Cart

I need to integrate with PayPal for cart payment because the client has used them for years and doesn’t want to change.

Their guides are horrid to work with. Information everywhere and it’s hard to work out what goes with what.

I’ve managed to get the core part working with some js embed code but I don’t know how to turn static product items into dynamic ones.

This is the portion of javascript I want to make dynamic by looping through the cart data.

    createOrder: function(data, actions) {
    return actions.order.create({
    "purchase_units": [{
    "amount": {
    "currency_code": "GBP",
    "value":dmx.parse('connWebsite.data.TotalToPay'),
    "breakdown": {
    "item_total": { /* Required when including the `items` array */
    "currency_code": "GBP",
    "value":dmx.parse('connWebsite.data.TotalToPay')
    }
    }
    },
    "items": [
    {
    "name": "First Product Name", /* Shows within upper-right dropdown during payment approval */
    "description": "Optional descriptive text..", /* Item details will also be in the completed paypal.com transaction view */
    "unit_amount": {
    "currency_code": "GBP",
    "value": "20"
    },
    "quantity": "1"
    },
    {
    "name": "Second Product Name", /* Shows within upper-right dropdown during payment approval */
    "description": "Optional descriptive text..", /* Item details will also be in the completed paypal.com transaction view */
    "unit_amount": {
    "currency_code": "GBP",
    "value": "20"
    },
    "quantity": "1"
    },
    ]
    }]
    });
    },

I have First and Second products there which are added to the PayPal cart fine. But I want to create the repeat for the items array and then replace "name": "First Product Name" with "name":dmx.parse('connWebsite.data.ItemName').

I think I’m fine with it all apart from the actual repeater code.

Can anyone assist for me?

I have literally just written some code to pass a data store basket to PayPal this afternoon. Give me 30 mins and I will publish it.

1 Like

That would be awesome. Thanks Brian.

My daughter in-law contacted me this morning and said she was giving up trying to be a web-dev and could not manage wappler, it was too hard,. she wanted to use PayPal but only Stripe was supported (rookie error).
Her site is completely static, databases scare her at the moment which severely limited me. The product details are held in a data store “id=store”

i have adopted a very different method than your idea and I am the first to acknowledge it is not as secure as it should be YET. It is very much a V1.0.0
Instead of doing it through .js i have created page within Wappler which creates the form needed to pass the basket to PayPal.
The page can be called from an anchor button, no parameters needed
The form has no output as such, all inputs hidden and no submit button as the form is auto submitted on the app ready() event
I have supressed caching and use the preloader to hide the content as the preloader does not seem to clear until the page load
So no inputs need to be sent from the basket as the data is taken directly from the data store.#
This was written for a php server but the script should be compatible with any platform. All,pure Wappler, no custom code at all

I think the easiest is just to paste the entire page code.


<!doctype html>

<html>
<head>
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" content="0" />
<base href="/">
<script src="dmxAppConnect/dmxAppConnect.js"></script>
<meta charset="UTF-8">
<title></title>

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.14.0/css/all.css" integrity="sha384-HzLeBuhoNPvSl5KYnjx0BT+WB0QEEqLprO+NBkkk5gbc67FTaL7XIGa2w1L0Xbgc" crossorigin="anonymous" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="bootstrap/5/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="dmxAppConnect/dmxDatastore/dmxDatastore.js"></script>
<link rel="stylesheet" href="dmxAppConnect/dmxPreloader/dmxPreloader.css" />
<script src="dmxAppConnect/dmxPreloader/dmxPreloader.js"></script>
<meta name="robots" content="noindex">
</head>
<body is="dmx-app" id="mystore" dmx-on:ready="form1.submit()">
<dmx-preloader id="preloader1" spinner="chasingDots"></dmx-preloader>
<dmx-datastore id="store"></dmx-datastore>
<div class="container">
<div class="row">
<div class="col">
<form id="form1" action="https://www.paypal.com/cgi-bin/webscr">
<input name="cmd" type="hidden" value="_cart">
<input name="upload" type="hidden" value="1">
<input type="hidden" name="currency_code" value="GBP">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" name="business" value="mail@paypal.email">
<!-- Specify the items  -->
<div id="repeat1" is="dmx-repeat" dmx-bind:repeat="store.data">
<input id="text3" dmx-bind:name="'item_name_'+($index+1)" type="hidden" class="form-control" dmx-bind:value="product_name">
<input id="text2" dmx-bind:name="'amount_'+($index+1)" type="hidden" class="form-control" dmx-bind:value="product_price*quantity">
<input id="text4" dmx-bind:name="'quantity_'+($index+1)" type="hidden" class="form-control" dmx-bind:value="quantity">
</div>
<!-- hideDisplay the payment button, code only commented out imn case needed for debugging. -->
<!-- <input type="image" name="submit" border="0" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif" alt="Buy Now"> <img alt="" border="0" width="1" height="1" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif"> -->
</form>
</div>
</div>
</div>
<script src="bootstrap/5/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Also for additional security add this before the html head tag

<?php if ($_SERVER['SERVER_NAME'] !="mydomain.com") {
  header("Location: https://mydomain.com/page.php");  
}
?>

Obviously changing ‘mydomain.com’ etc to the correct values for your site
Anyone want to offer suggestions for improvement, comments welcome

Thanks Brian. This is actually the solution I was using previously but I wanted to use the latest PayPal Checkout integration but hit a wall with the repeat syntax within js code instead of html.

No problem, if you work out the .js way you can always share it back :grinning:

1 Like

I sure will. Hoping one of the Wappler team can chip in and give me the steer I need.

sadly my .js is quite weak. I actually bought some books on it the other day to get up to speed!

1 Like

Can anyone help with this? How to make part of the js script loop is what I need help with.

“items” in your JavaScript is expecting an array, so you can point to any array in your dmx app.

“items”: dmx.app.data.myarray 

To find the actual path to your array, you can execute dmx.app.data in the dev console and find your array.

Just make sure the array has the exact elements the js needs. You can always insert into a datastore in order to get the element names correct, and then point the js to that.

1 Like

Wow, massive thanks Ken. It looks like you’ve absolutely nailed it. I was stuck in the rut of having loops to add the data and completely overlooked the fact that it’s an array.

I will do as you suggest and let you know how it goes.

Cheers, Jon.

Hi Ken

I thought you’d cracked it and it was going to be easy but I just can’t get it to work.

“items”: dmx.app.data.datastore1
or
“items”: dmx.app.data.datastore1.data

are both failing. I’ve populated the datastore with the same structure but it just isn’t liking it.

Screenshot 2022-02-19 at 14.34.18

Are you able to offer me any steer or advice on how to get it to work?

It looks as those you have the correct array going in.

Aside from general troubleshooting, timing is often an issue with scripts if they run on page load. Make sure the script actually has all the data when it is running.

Thanks Ken. I am pretty confident it has all the data. The datastore is populated using a Page Flow on page load and I’ve disabled that so it uses the data already in there in case it was a delay issue but still no joy.

After poking around in the Wappler code, try dmx.app.datastore_datastore1.data

Thanks Brian. That doesn’t show any data I’m afraid.

It seems that dmx.app.data.datastore1.data is where it is but, for some reason, PayPal doesn’t like it.

I’ve had to abort the js route and go back to the form method you posted earlier in this thread. It’s a shame but at least it works.

Cheers again, much appreciated.

1 Like

Hi Brian. Has PayPal just changed how their https://sandbox.paypal.com/cgi-bin/webscr process so you can no longer pay by card but instead have to have a PayPal account? I finished my integration last weekend but now it looks to be different when clicking the submit button and going to PayPal’s site.

I’m curious to know if you’re having the same issue.

Cheers, Jon.

Just checked and yes, that appears to be the case now.
Off out now (wife’s birthday) but will look into it when i get a chance

1 Like

Have just checked the site i sent live last week and cards can still be taken on live site, not looked at sandbox

I can confirm that on testing the card payments option does not appear in the sandbox version however it does function normally when using PayPal in live situation

1 Like