Sign inSign up

prengineer/paypal-ipn-integration

By prengineer

Updated almost 2 years ago

This is a standalone container that you can use to perform PayPal IPN transactions.

Image
Integration & delivery
0

207

prengineer/paypal-ipn-integration repository overview

image

Please Support This Project!

This project is being developed during my spare time. I would appreciate a donation if you found it useful.

You can also support me by sending a BitCoin donation to the following address:

19JXFGfRUV4NedS5tBGfJhkfRrN2EQtxVo

Image Architectures


ArchitectureAKA
amd64x64
arm64aarch64

Implementation Stacks


StackVersion
PHP8.1

About

This is a standalone container that you can use to perform PayPal IPN transactions.

What does it do?

It receives a POST from your application with the information to initiate a PayPal transaction. It submits the transaction to PayPal. Then, it processes the IPN notification from PayPal. If the transaction is validated/successful, it forwards the information to your application for processing.

Application scenarios

  1. Your application submits the POST to this container. It will show the user a page letting them know that they are being transferred to PayPal to complete the checkout. The container waits the time that you specify. The container then submits the transaction details by redirecting the user.

  2. The user cancels the PayPal checkout. PayPal will redirect them back to the container (You must provide the return URL for cancellations, like: https://payments.mystore.com/index.php?action=cancel). They will see a notification that the transaction was cancelled and will be transferred to the Cart page of your application after a wait time that you determine.

  3. The user completes the PayPal checkout. PayPal will redirect the user back to the container (You must provide the return URL for cancellations, like: https://payments.mystore.com/index.php?action=complete). They will see a notification that the checkout was completed and will be transferred to the Orders page of your application after a wait time that you determine.

  4. PayPal submits an Instant Payment Notification. Upon the completion of the checkout, PayPal will then send an IPN to a hidden endpoint (the user doesn't see it). (You must provide the return URL, like: https://payments.mystore.com/index.php?action=ipn) The container will perform the validation (submitting the information back to PayPal for confirmation) and if the response from PayPal is that the transaction is "VERIFIED", then passes the IPN data to your application on a script that you specify in an ENV variable.

NOTE: You can implement your own Cancel and Complete pages if you want, instead of relying on the container's. Just change the URL that is configured in the container's ENV variables. You do need to POST to the root inside the container (https://payments.mystore.com/index.php) and use the <<action=ipn>> endpoint though (https://payments.mystore.com/index.php?action=ipn). This is assuming that you host this container in https://payments.mystore.com.

Application endpoints


Base URLEndpointRequiredPurpose
pay.site.com/index.phpYESInitiate the transaction
pay.site.com/index.php?action=cancelNOAcknowledge transaction cancellation
pay.site.com/index.php?action=completeNOAcknowledge completed checkout
pay.site.com/index.php?action=ipnYESPerform IPN validation

How to deploy to Kubernetes

This just shows how to build the deployment manifest. You also have to create your own Service, Ingress, etc.

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pp-ipn-deployment
  namespace: pp-ipn
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pp-ipn
  template:
    metadata:
      labels:
        app: pp-ipn
    spec:
    # Specify the container
      containers:
        - name: pp-ipn
          image: prengineer/paypal-ipn-integration:php81
          env:
            # Time Zone
            - name: TZ
              value: "America/New_York"
            # production | sandbox
            - name: PAYPAL_INSTANCE
              value: "sandbox"
            # [ no | console | file | both ]
            - name: PAYPAL_LOG_MODE
              value: "console"
            # [ low | medium | high | debug ]
            - name: PAYPAL_LOG_LEVEL
              value: "low"
            # Time to show the Loading, Cancelled, and Completed pages before redirecting, in seconds
            - name: PAYPAL_LOAD_TIME
              value: "5"
            # URL of the page that will process the completed transaction details
            - name: PROCESSING_URL
              value: "https://pay.site.com/Processing.php"
            # URL of the page that displays the shopping cart
            - name: CART_URL
              value: "https://pay.site.com/Cart.php"
            # URL of the page that displays the orders
            - name: ORDERS_URL
              value: "https://pay.site.com/Orders.php"
          ports:
            - name: httpport
              containerPort: 80

Environment Variables


VariableValuesDetails
TZUse Standard for thisThe Time Zone for the Web Server to use
PAYPAL_INSTANCEproductionUses the real endpoint for Live deployments
"sandboxUses the fake endpoint for Testing
PAYPAL_LOG_MODEnoDoesn't log anything, except errors (always to console at least)
"consoleLogs everything to the container console
"fileLogs everything to a file (/app/PayPal-IPN-Integration-Logs.txt)
"bothLogs everything to both the console and to a file (/app/PayPal-IPN-Integration-Logs.txt)
PAYPAL_LOG_LEVELlowOnly logs the IPN result
"medAdds transaction submissions
"highAdds code tracing
"debugAdds debug logs and variable dumps to pages
PAYPAL_LOAD_TIMEnumberTime in seconds to wait before redirecting
PROCESSING_URLA page in your applicationThe URL of the page that will receive the completed transaction details for processing
CART_URLThe URL of the Shopping Cart in your applicationThe URL of the Shopping Cart in your application
ORDERS_URLThe URL of the Order History in your applicationThe URL of the Order History in your application

How to initiate a transaction

These are example forms that submit the data required by the container to process a transaction. Follow the https://developer.paypal.com documentation to identify the fields to submit.

Donation.html:

<!-- Example of how to submit a PayPal Donation transaction -->

<h3>Donation form data is hidden</h3>

<form action="pay.site.com/index.php" method="POST">

  <!-- PayPal Command -->
  <input type="hidden" name="cmd" value="_donations">
  <input type="hidden" name="rm" value="2">

  <!-- Return URLs -->
  <input type="hidden" name="return" value="https://pay.site.com/index.php?action=complete">
  <input type="hidden" name="cancel_return" value="https://pay.site.com/index.php?action=cancel">
  <input type="hidden" name="notify_url" value="https://pay.site.com/index.php?action=ipn">

  <!-- Taxes and Currency -->
  <input type="hidden" name="currency_code" value="USD">
  <input type="hidden" name="lc" value="US">
  
  <!-- Item -->
  <input type="hidden" name="item_name" value="Donation">
  <input type="hidden" name="item_number" value="1">
  <input type="hidden" name="amount" value="5">

  <!-- Configurations -->
  <input type="hidden" name="charset" value="utf-8">
  <input type="hidden" name="no_note" value="1">
  <input type="hidden" name="no_shipping" value="1">

  <!-- Business e-mail -->
  <input type="hidden" name="business" value="[email protected]">
  
  <input type="submit" value="Submit">

</form>

ShoppingCart.html:

<!-- Example of how to submit a PayPal Shopping Cart transaction -->

<h3>Shopping Cart form data is hidden</h3>

<form action="pay.site.com/index.php" method="POST">

  <!-- PayPal Command -->
  <input type="hidden" name="cmd" value="_cart">
  <input type="hidden" name="upload" value="1">
  <input type="hidden" name="rm" value="2">

  <!-- Return URLs -->
  <input type="hidden" name="return" value="https://pay.site.com/index.php?action=complete">
  <input type="hidden" name="cancel_return" value="https://pay.site.com/index.php?action=cancel">
  <input type="hidden" name="notify_url" value="https://pay.site.com/index.php?action=ipn">

  <!-- Taxes and Currency -->
  <input type="hidden" name="currency_code" value="USD">
  <input type="hidden" name="lc" value="US">
  <input type="hidden" name="tax_cart" value="300">
  <input type="hidden" name="handling_cart" value="15">
  
  <!-- Start Items -->
  <input type="hidden" name="item_name_1" value="TCL 55in LCD TV">
  <input type="hidden" name="item_number_1" value="100564">
  <input type="hidden" name="amount_1" value="300">
  <input type="hidden" name="quantity_1" value="1">

  <input type="hidden" name="item_name_2" value="Raspberry Pi 4B 4GB">
  <input type="hidden" name="item_number_2" value="200438">
  <input type="hidden" name="amount_2" value="50">
  <input type="hidden" name="quantity_2" value="1">

  <input type="hidden" name="item_name_3" value="1TB SSD Drive">
  <input type="hidden" name="item_number_3" value="3004179">
  <input type="hidden" name="amount_3" value="70">
  <input type="hidden" name="quantity_3" value="5">
  <!-- End Items -->

  <!-- Configurations -->
  <input type="hidden" name="charset" value="utf-8">
  <input type="hidden" name="no_note" value="1">
  <input type="hidden" name="no_shipping" value="1">

  <!-- Business e-mail -->
  <input type="hidden" name="business" value="[email protected]">
  
  <input type="submit" value="Submit">

</form>

Processing the transaction

Once the validation is completed, your processing script will receive a POST with the data that was validated against the PayPal systems.

The field 'payment_status' will have either the "Complete" or "Failed" values. Perform your processing based on that.

NOTE: Make sure that the result POSTs come from your systems when processing.

This is an example of a response:

Array
(
    [mc_gross] => 5.00
    [protection_eligibility] => Eligible
    [payer_id] => 9CC5TTVWYFN4S
    [payment_date] => 11:53:55 Oct 05, 2024 PDT
    [payment_status] => Completed ( or Failed )
    [charset] => UTF-8
    [first_name] => John
    [mc_fee] => 0.63
    [notify_version] => 3.9
    [payer_status] => verified
    [business] => [email protected]
    [quantity] => 1
    [verify_sign] => AQSDRlOdLI5KC69HSwEwbtIyselsATulT4PHOUs3kYhhaqN7CnjtZ7gM
    [payer_email] => [email protected]
    [txn_id] => 7N938458884538933
    [payment_type] => instant
    [last_name] => Sender
    [receiver_email] => [email protected]
    [payment_fee] => 0.63
    [shipping_discount] => 0.00
    [receiver_id] => AGGTYF4AXB1RS
    [insurance_amount] => 0.00
    [txn_type] => web_accept
    [item_name] => Donation
    [discount] => 0.00
    [mc_currency] => USD
    [item_number] => 12345
    [residence_country] => US
    [test_ipn] => 1
    [shipping_method] => Default
    [transaction_subject] => pay.site.com/donations
    [payment_gross] => 5.00
    [ipn_track_id] => d973613d04115
)

Tag summary

Content type

Image

Digest

sha256:6d0e333ac

Size

77.6 MB

Last updated

almost 2 years ago

docker pull prengineer/paypal-ipn-integration:php-8.1