Skip to main content
Version: 1.28 (Current)

PayPal - Parse IPN Request

Audience: Low-code Engineers

Skill Prerequisites: Actions, Tokens, API endpoints

Reads a PayPal Instant Payment Notification (IPN) and turns each of its fields into a token, for example [Ipn:txn_type] or [Ipn:payer_email]. Use it in an API endpoint that PayPal posts its notifications to.

The action only reads the message. It doesn't check with PayPal that the message is genuine, so verify it before you act on it. See Security.

note

This action is part of the PayPal add-on (DnnSharp.PayPal). The add-on is installed separately and needs the PAYPAL feature in your license. If it isn't licensed, the action fails with a "not licensed" error. If you don't see the PayPal actions, the add-on isn't installed.

Typical Use Cases​

  • Build your own IPN handler in an API endpoint, for example to record every subscription payment
  • Track subscriptions created by PayPal - Express Checkout for longer than its built-in 7-day window
  • Parse an IPN message that was saved earlier, for example to reprocess it

Don't use it to​

Action NameDescription
PayPal - Express CheckoutTakes the payment or creates the subscription that the IPN reports on. It explains the whole PayPal flow.
Get Transaction DetailsAsks PayPal for the details of a transaction, for example the txn_id of an IPN.
Cancel Express Checkout SubscriptionCancels a subscription by its profile ID.
Run SQL QuerySaves the IPN data in your database.

Input Parameter Reference​

ParameterDescriptionSupports TokensDefaultRequired
Request DataThe IPN message, URL-encoded, for example recurring_payment_id=I-DF3S35GWL16Y&profile_status=Active&.... Leave it empty to read the body of the current HTTP request, which is what PayPal posts to your API endpoint.Yesempty stringNo
TokenPrefixText added in front of every token name, for example Ipn: for [Ipn:payer_email]. It's added as typed, with nothing in between.Yesempty stringNo

Output Parameters Reference​

The action has no output parameters. It creates one token for every field in the message, named TokenPrefix plus the field name. Values are URL-decoded. PayPal decides which fields it sends, and they depend on the notification type. The action's help text lists these common fields for subscriptions:

recurring_payment_id, profile_status, payer_id, payer_email, payer_status, last_name, first_name, initial_payment_amount, amount, product_name, product_type, payment_cycle, amount_per_cycle, next_payment_date, period_type, receiver_email, time_created, currency_code, residence_country, verify_sign, test_ipn, tax, txn_type, shipping, charset, notify_version, outstanding_balance and ipn_track_id.

The profile_status can be Created, Updated, Active, Suspended or Cancelled. Use txn_type to tell the notification types apart, for example recurring_payment or recurring_payment_profile_cancel.

Security​

An IPN handler is a public address, and anyone can post to it. Before you grant access, mark an order as paid or change a subscription, check the message:

  • Confirm it with PayPal. For notifications about a payment, look up the txn_id with Get Transaction Details and use the status and amount PayPal returns. PayPal also documents a postback check, where you send the message back to PayPal and it answers VERIFIED or INVALID. You can do that with Server Request.
  • Check that it's for you. Compare receiver_email with your PayPal account's email.
  • Handle repeats. PayPal may send the same notification more than once. Save ipn_track_id or txn_id and skip messages you've already processed.

Considerations​

  • Always use a prefix. Without one, the fields are saved with their plain names, like amount or first_name, and replace any tokens with the same names. Since the sender chooses the field names, a prefix such as Ipn: keeps the message from overwriting your own tokens.
  • Tell PayPal where to post. Set your API endpoint's URL as the IPN address in your PayPal account's profile, or send it as the notify URL of the payment.
  • Reply quickly. PayPal resends a notification if it doesn't get a successful response. If your actions fail with an error, expect the same message again.
  • It needs a request. With Request Data empty, the action reads the current HTTP request. Where there's no request, such as a scheduled job, fill in Request Data.
  • Test in the sandbox. PayPal's sandbox sends test notifications with test_ipn set to 1. Ignore those in production.

Examples​

tip

To understand how to use the below examples, please see Running Examples.

1. Read the IPN that PayPal posted to an API endpoint​

This action reads the body of the request and creates tokens that start with Ipn:, for example [Ipn:recurring_payment_id], [Ipn:profile_status] and [Ipn:txn_id].

{
"Title": "PayPal - Parse IPN Request",
"ActionType": "ParseIPNRequest",
"Description": "Read the PayPal notification",
"Parameters": {
"RequestData": "",
"TokenPrefix": "Ipn:"
}
}

2. Confirm a subscription payment before recording it​

These actions run after example 1. The first one asks PayPal for the transaction in the IPN, and only for real payments to your account. The second parses PayPal's answer. The third records the payment only if PayPal says it's completed. The credentials come from tokens.

[
{
"Title": "Get Transaction Details",
"ActionType": "PayPal.GetTransactionDetails",
"Description": "Confirm the payment with PayPal",
"Condition": "[Ipn:txn_type] == \"recurring_payment\" && [Ipn:receiver_email] == [PayPalAccountEmail]",
"Parameters": {
"PayPalExpressId": "[PayPalApiUser]",
"PayPalExpressPassword": "[PayPalApiPassword]",
"PayPalExpressSignature": "[PayPalApiSignature]",
"PayPalExpressLiveMode": true,
"TransactionId": "[Ipn:txn_id]",
"JsonToken": "PayPalTransactionJson"
}
},
{
"Title": "Parse JSON Into Tokens",
"ActionType": "ParseJsonIntoTokens",
"Description": "Read PayPal's answer",
"Condition": "[PayPalTransactionJson] != \"\"",
"Parameters": {
"JsonString": "[PayPalTransactionJson]",
"BaseTokenName": "Txn"
}
},
{
"Title": "Run SQL Query",
"ActionType": "RunSql",
"Description": "Record the subscription payment",
"Condition": "[Txn:ACK] == \"Success\" && [Txn:PAYMENTSTATUS] == \"Completed\"",
"Parameters": {
"SqlQuery": "INSERT INTO SubscriptionPayments (ProfileId, TransactionId, Amount, IpnTrackId) VALUES (@ProfileId, @TransactionId, @Amount, @IpnTrackId)",
"BindTokens": [
{
"name": "ProfileId",
"value": "[Ipn:recurring_payment_id]"
},
{
"name": "TransactionId",
"value": "[Ipn:txn_id]"
},
{
"name": "Amount",
"value": "[Txn:AMT]"
},
{
"name": "IpnTrackId",
"value": "[Ipn:ipn_track_id]"
}
]
}
}
]

Revised 09/27/2026