Presenting custom prices with Paddle.com's v2 JavaScript API ("Billing" API)

62 Views Asked by At

I want to use Paddle.Checkout.open() with the override parameter (or data-override in html, which is practically the same) so that I can present a custom price (which I calculated dynamically and generated the URL for with the Pay Link function).

Paddle.Checkout.open({
    override: '... pay link goes here ...'
});

This triggers an error thru the eventCallback, saying:

API Error: The transaction id field is required when items is not present.

I don't understand where to get the transaction ID from. The docs say:

When you open a checkout, Paddle.js automatically creates a transaction for you.

That's what I am doing, am I not?

In fact, when I open the generated override URL in a web browser directly, it opens the checkout page just fine. All I want is that this URL is opened as an overlay now.

So, how to I use the override URL in order to have a checkout with a custom price?

Update

I figured out that I can create a transaction beforehand, but that's unsafe because it requires me to pass the secret "API ID" in the open (i.e. in the frontend source code), which is a no-go:

var request = new XMLHttpRequest();
let async = true;
request.open("POST", "https://sandbox-api.paddle.com/transactions", async);
request.setRequestHeader("Authorization", "Bearer <my API key would go here>");
request.setRequestHeader("Content-type", "application/json;charset=UTF-8");
request.onload = function () {
    console.log("transaction: " + request.responseText);
};
let data = {
    items: [
        {
            quantity: 1,
            price: {
                description: "test",
                unit_price: { currency_code: "USD", amount: "123" },
                product_id: "pro_01hjs2k565…"
            }
        }
    ]
};
console.log("create transaction", data);
request.send(JSON.stringify(data));

I can do that part in my backend, at least, though I would only go down that route as a last resort. In my understanding, me supplying a transaction id shouldn't be necessary because it's already inside the prepared Pay link somewhere (similar to why I don't need to supply the id when I supply an items array).

1

There are 1 best solutions below

0
Thomas Tempelmann On BEST ANSWER

Turns out that the documentation for using this parameter is for the older (deprecated) "Classic" API, and I'm building with the newer "Billing" API, which won't even use the override parameter (though, sadly, it doesn't say so in the error message).

Further investigation showed, however, that I can use the very id value from the "Pay Link" call - that one is all I need to show the custom price, by updating the onload handler function as follows:

        request.onload = function () {
            let response = JSON.parse(request.responseText);
            var txnId = response.data.id;
            console.log("transaction id: " + txnId);
            // and do the checkout:
            Paddle.Checkout.open({
                transactionId: txnId
            });
        };

This works, though it still exposes the secret API key in the JS code, which everyone can read. It's safer to move this part into the backend of of my own server.