paddle

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


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).

Update 2 (19Jul24)

Custom prices were not allowing us to provide a custom message, though. A few weeks ago, Paddle fixed this.

Now you can add a "name" parameter to the price record, and its value will then appear on the purchase (both in the web view and in the receipt PDF). Make sure to also include the "description" field, though - even though Paddle told me that it's only for internal use, the request currently won't go through if it's missing.


Solution

  • 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 returned from the "create transaction" call (see the code with the XMLHttpRequest in my question) - 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.

    For that reason, I recommend to move the part that creates the transaction into the server backend where one cannot easily peek into your code.