Where is the PayPal Subscription ID and Transaction ID in a PAYMENT.SALE.COMPLETED webhook event? How to get their details?

Viewed 842

I'm using PayPal subscription API with php.

So far I know that with a successful payment the PAYMENT.SALE.COMPLETED event is triggered. But the object contains only a billing agreement id and seems not related to the subscription. How can I get more details about customer and the payment?

Content of example webhook


{
    "id": "WH-1J525465EH157100Y-81K24252LY536784P",
    "create_time": "2021-03-10T18:22:33.292Z",
    "resource_type": "sale",
    "event_type": "PAYMENT.SALE.COMPLETED",
    "summary": "Payment completed for EUR 5.0 EUR",
    "resource": {
        "billing_agreement_id": "I-8XRLDA4MNEW3",
        "amount": {
            "total": "5.00",
            "currency": "EUR",
            "details": {
                "subtotal": "5.00"
            }
        },
        "payment_mode": "INSTANT_TRANSFER",
        "update_time": "2021-03-10T18:22:13Z",
        "create_time": "2021-03-10T18:22:13Z",
        "protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
        "transaction_fee": {
            "currency": "EUR",
            "value": "0.45"
        },
        "protection_eligibility": "ELIGIBLE",
        "links": [
            {
                "method": "GET",
                "rel": "self",
                "href": "https://api.sandbox.paypal.com/v1/payments/sale/1P642136UK709905M"
            },
            {
                "method": "POST",
                "rel": "refund",
                "href": "https://api.sandbox.paypal.com/v1/payments/sale/1P642136UK709905M/refund"
            }
        ],
        "id": "1P642136UK709905M",
        "state": "completed",
        "invoice_number": ""
    },
    "status": "SUCCESS",
    "transmissions": [
        {
            "webhook_url": "https://musily.de/payment/webhook/paypal.php",
            "http_status": 200,
            "reason_phrase": "HTTP/1.1 200 Connection established",
            "response_headers": {
                "Accept-Ranges": "none",
                "Server": "Apache/2.4.46 (Unix)",
                "Cache-Control": "max-age=172800",
                "Expires": "Fri, 12 Mar 2021 18:23:16 GMT",
                "Content-Length": "65",
                "Date": "Wed, 10 Mar 2021 18:23:16 GMT",
                "X-Powered-By": "PHP/7.3.27",
                "Content-Type": "text/html"
            },
            "transmission_id": "a7472af0-81cd-11eb-aacd-47b3747d966f",
            "status": "SUCCESS",
            "timestamp": "2021-03-10T18:23:03Z"
        }
    ],
    "links": [
        {
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1J525465EH157100Y-81K24252LY536784P",
            "rel": "self",
            "method": "GET",
            "encType": "application/json"
        },
        {
            "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-1J525465EH157100Y-81K24252LY536784P/resend",
            "rel": "resend",
            "method": "POST",
            "encType": "application/json"
        }
    ],
    "event_version": "1.0"
}

2 Answers
    "billing_agreement_id": "I-8XRLDA4MNEW3",

That is your subscription's ID right there.

    "id": "1P642136UK709905M",

That is your PayPal transaction / sale / capture ID right there.

    "links": [
       {
           "method": "GET",
           "rel": "self",
           "href": "https://api.sandbox.paypal.com/v1/payments/sale/1P642136UK709905M"
       },
       {

There's how to get details about the sale (the v2/payments/captures API might also work, not sure)

As @Preston-PHX said billing_agreement_id is a subscription id, but if you need to get subscription name and similar details:

  1. Get billing_agreement_id and call subscriptions api, reply would be details on the customer and small details on subscription:

function getsubdetails($id)
                {  
                $header = array(); 
                $header[] = 'Content-type: application/json';
                $header[] = 'Authorization: Bearer '.$this->token;
                $url = 'https://api-m.sandbox.paypal.com/v1/billing/subscriptions/'.$id;
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
                curl_setopt($ch, CURLOPT_URL,$url); 
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
                $server_output = curl_exec($ch);
                return $server_output;
                 curl_close ($ch);
                 }   
  1. Get plan_id and call plans api, reply would be all details on subscription:
   public function getplandetails($id)
    {
     
    $header = array(); 
    $header[] = 'Content-type: application/json';
    $header[] = 'Authorization: Bearer '.$this->token;
    
    
        
    $url = 'https://api-m.sandbox.paypal.com/v1/billing/plans/'.$id;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_URL,$url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    $server_output = curl_exec($ch);
    return $server_output;
    
    curl_close ($ch);
    
    
    }

Full code:

 include 'paypal.php'; //contains above code inside Paypal class
     $paypal = new Paypal;
     $paypal->setcredentials($clientid,$secret); //setting api credentials, create this function near above code
     $paypal->gettoken(); // initiating token, create this function near above code

     $subdetails = $paypal->getsubdetails($planid); //sending billing_agreement_id
     $subdetails2 = json_decode($subdetails,true);
     $planid = $subdetails2['plan_id']; //received plan_id
     $plandetails = $paypal->getplandetails($planid); // sending it to get subscription name
     $plandetails2 = json_decode($plandetails, true);
     $this->planname = $plandetails2['name']; 


Related