javascriptpaypalpaypal-ipn

Paypal Update Notification URL Or Use Dynamic URL


I want to trigger an ipn.php file once someone uses the Paypal Smart Button. I've tried updating the Notification URL in my account but the value won't update and it still uses the old url which no longer works, despite showing that I've change the URL in the input field.

I've tried to do a dynamic aproach with notify_url like this:

paypal.Buttons({
    style : {
        shape: 'rect',
        color: 'gold',
        layout: 'vertical',
        label: 'paypal',
    },
    createOrder : (data, actions) => {
        return actions.order.create({
            purchase_units: [{
                description : Payment.description,
                custom_id: Payment.description,
                amount : {
                    currency_code: "USD",
                    value: Payment.amount
                },
                notify_url: 'https://www.my-new-url.com/ipn.php'
            }],
            application_context: {
                shipping_preference : 'NO_SHIPPING'
            }
        })
    },
    onApprove : (data, actions) => {
        return actions.order.capture().then(function(orderData) {
            console.log('Capture result', orderData, JSON.stringify(orderData, null, 2))
        })
    },
    onError : (err) => {
        console.log(err)
    }
}).render('#paypal-button-container')

However it still did not work. Am I using notify_url wrong? How can I make this work?

I'd like to either know how I can force the Notification URL to update in my account or how to use the notify_url parameter in order to set the Notification URL dynamically, either is fine. Any ideas how to achieve this?


Solution

  • The parameters you can use are the same as those documented for the Create Order API call .. notify_url (or equivalent) is not one of them, because IPN is very old and should be deprecated. Why are you using it with a new integration of a PayPal JS SDK button?

    In general there is no reason to wait for asynchronous notifications. You can get an immediate, synchronous notification of completed payments by combining the JS SDK for approval with a backend for order creation and capture.

    Use the v2/checkout/orders API and make two routes (url paths) on your server, one for 'Create Order' and one for 'Capture Order'. You could use one of the (recently deprecated) Checkout-*-SDKs for the routes' API calls to PayPal, or your own HTTPS implementation of first getting an access token and then doing the call. Both of these routes should return/output only JSON data (no HTML or text). Inside the 2nd route, when the capture API is successful you should verify the amount was correct and store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as reserving product or sending an email) immediately before forwarding return JSON to the frontend caller. In the event of an error forward the JSON details of it as well, since the frontend must handle such cases.

    Pair those 2 routes with this frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server . (If you need to send any additional data from the client to the server, such as an items array or selected options, add a body parameter to the fetch with a value that is a JSON string or object)


    If for some reason you actually need an asynchronous, after-the-fact notification of payment completion (unclear why you would need it), Webhooks are the newer replacement to IPN.