简体   繁体   中英

How to Send Custom data fields in PayPal Smart Button transaction

I am new to PayPal integrations but I have managed to use the client-side JavaScript SDK to create a button and complete a transaction. I have also added a webhook that listens for PAYMENT.CAPTURE.* events and log the return data into my transactions table in my own database. The downside is I do not have a way of tracking for which service or customer the transaction was. So I would like to know how I can add at least one custom field in the button so that it is returned back to me in the webhook POST so that I can perform some business logic for that particular customer.

My initial alternative was to POST the data return onApprove:(data, actions)=>{} but I would have not recovery option if something catastrophic happens before that is done eg Power outage or general Client-Server connection failure.

Here is my JS basic code for now:

try{
        paypal.Buttons({

        // Set up the transaction
        createOrder: function(data, actions) {
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: charge.amount,
                        currency_code:'USD'
                    }
                }]
            });
        },
        // Finalize the transaction
        onApprove: function(data, actions) {
            return actions.order.capture().then(function(details) {
                console.log(details);
                if(details.status == "COMPLETED"){
                  localStorage.clear();
                  window.location.href = "thank-you";
                }
                //alert('Transaction completed by ' + details.payer.name.given_name + '!');
            });
        }


    }).render('#paypal-button-container');
  }catch(e){
     console.error('PayPal not loaded!');
  }

Switch to a proper client-server integration.

Here is the front-end to use: https://developer.paypal.com/demo/checkout/#/pattern/server

You will need two corresponding routes on your server, 'Set Up Transaction' and 'Capture Transaction', documented here: https://developer.paypal.com/docs/checkout/reference/server-integration/

(If you want to be a little bit frankensteiny, you could try keeping your createOrder function as-is (client-side code) and integrating a single server-side route only in the onApprove section. I don't really recommend this, but you could try it, maybe as an iterative development step. Best to 'Set Up Transaction' from your server as well.)


With the above solution, you have an immediate, synchronous API response on payment capture. There is no need for an additional asynchronous notification from webhooks, so those will basically become superfluous to you.

You can add 'custom_id' field in creareOrder function like that:

    createOrder: function(data, actions) {
        return actions.order.create({
          purchase_units: [{
            custom_id: customValue,
            amount: {
              value: price
            }
          }]
        });
      },

You can switch to a client-server integration (as per @Preston PHK's answer), but for that may be overkill for some applications (and not what the OP asked for).

For a simple purchase where you just need to pass some specific information, you can try leveraging the purchase_units.invoice_id field (assuming you don't need that for something else).

The caveat is that the invoice_id needs to be unique every time you use it. This means that you can't just use your customer's internal id. You would need to add something extra to ensure uniqueness.

Your createOrder call might then look something like this:

createOrder: function(data, actions) {
    return actions.order.create({
        purchase_units: [{
            invoice_id: customerId + "-" + randString,
            amount: {
                value: charge.amount,
                currency_code:'USD'
            }
        }]
    });
},

A 6 character random string of alphanumeric (upper and lower) characters gives over 56 billion possibilities, which for most purposes should provide sufficient uniqueness. If you want to be even safer, make it longer. I'm not sure of the exact limit on invoice_id but I think it's at least 40 characters.

When you process the transaction (from a webhook) on your server, you just throw away the extra characters.

$custId = substr($invoice_id, 0, -7);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM