Jump to content

Help with paypal 'capture' not being invoked


Chrisj

Recommended Posts

I am using a web video script that has Paypal integrated. Upon attempting a live transaction to test, the process proceeds to Paypal, shows the transaction amount and returns to the web site successfully, 
however, no amount is added to the website and no amount is deducted from the paypal user account. I see no errors at paypal or on the website.
After communicating with Paypal Merchant Support they said: "You do need to work with your developer and request them to find out why the capture request would not be invoked after the order is created and approved and fix it accordingly".
However, the developer is unavailable, so I am attempting to find/fix the issue.
Can you tell me if you see anything that might cause an issue with the code below? Or any clues I might look into?
I look forward to any suggestions.

 

<?php
if (IS_LOGGED == false && $first != 'success_fortumo' && $first != 'success_aamarpay' && $first != 'cashfree_paid' && $first != 'iyzipay_paid' && $first != 'success_yoomoney') {
    $data = array(
        'status' => 400,
        'error' => 'Not logged in'
    );
    echo json_encode($data);
    exit();
}

require 'assets/includes/paypal_config.php';

$payment_currency = $pt->config->payment_currency;
$paypal_currency = $pt->config->paypal_currency;

if ($first == 'replenish') {
	$data    = array('status' => 400);
	$request = (!empty($_POST['amount']) && is_numeric($_POST['amount']));
	if ($request === true) {
		$price = PT_Secure($_POST['amount']);

		$ch = curl_init();

	    curl_setopt($ch, CURLOPT_URL, $url . '/v2/checkout/orders');
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	    curl_setopt($ch, CURLOPT_POST, 1);
	    curl_setopt($ch, CURLOPT_POSTFIELDS, '{
	      "intent": "CAPTURE",
	      "purchase_units": [
	            {
	                "items": [
	                    {
	                        "name": "Wallet Replenishment",
	                        "description":  "Pay For ' . $pt->config->name.'",
	                        "quantity": "1",
	                        "unit_amount": {
	                            "currency_code": "'.$pt->config->paypal_currency.'",
	                            "value": "'.$price.'"
	                        }
	                    }
	                ],
	                "amount": {
	                    "currency_code": "'.$pt->config->paypal_currency.'",
	                    "value": "'.$price.'",
	                    "breakdown": {
	                        "item_total": {
	                            "currency_code": "'.$pt->config->paypal_currency.'",
	                            "value": "'.$price.'"
	                        }
	                    }
	                }
	            }
	        ],
	        "application_context":{
	            "shipping_preference":"NO_SHIPPING",
	            "return_url": "'.PT_Link("aj/wallet/get_paid?status=success&amount=").$price.'",
	            "cancel_url": "'.PT_Link("aj/wallet/get_paid?status=false").'"
	        }
	    }');

	    $headers = array();
	    $headers[] = 'Content-Type: application/json';
	    $headers[] = 'Authorization: Bearer '.$pt->paypal_access_token;
	    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

	    $result = curl_exec($ch);
	    if (curl_errno($ch)) {
	        echo 'Error:' . curl_error($ch);
	    }
	    curl_close($ch);
	    $result = json_decode($result);
	    if (!empty($result) && !empty($result->links) && !empty($result->links[1]) && !empty($result->links[1]->href)) {
	        $data = array(
		        'status' => 200,
		        'type' => 'SUCCESS',
		        'url' => $result->links[1]->href
		    );
	    }
	    elseif(!empty($result->message)){
	        $data = array(
	            'type' => 'ERROR',
	            'details' => $result->message
	        );
	    }
	    echo json_encode($data);
	    exit();
	}
}

if ($first == 'get_paid') {
	$data['status'] = 500;
	if (!empty($_GET['amount']) && is_numeric($_GET['amount']) && !empty($_GET['token'])) {

		$amount = (int)PT_Secure($_GET['amount']);
		$token = PT_Secure($_GET['token']);

		include_once('assets/includes/paypal.php');

		$ch = curl_init();

		curl_setopt($ch, CURLOPT_URL, $url . '/v2/checkout/orders/'.$token.'/capture');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);

		$headers = array();
		$headers[] = 'Content-Type: application/json';
		$headers[] = 'Authorization: Bearer '.$pt->paypal_access_token;
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

		$result = curl_exec($ch);
		if (curl_errno($ch)) {
		    header("Location: " . PT_Link('wallet'));
			exit();
		}
		curl_close($ch);
		if (!empty($result)) {
		    $result = json_decode($result);
		    if (!empty($result->status) && $result->status == 'COMPLETED') {


		    	$update  = array('wallet' => ($user->wallet_or += $amount));
				$db->where('id',$user->id)->update(T_USERS,$update);
				$payment_data         = array(
		    		'user_id' => $user->id,
		    		'paid_id'  => $user->id,
		    		'admin_com'    => 0,
		    		'currency'    => $pt->config->paypal_currency,
		    		'time'  => time(),
		    		'amount' => $amount,
		    		'type' => 'ad'
		    	);
				$db->insert(T_VIDEOS_TRSNS,$payment_data);


				$_SESSION['upgraded'] = true;
				$url     = PT_Link('wallet');
				if (!empty($_COOKIE['redirect_page'])) {
		            $redirect_page = preg_replace('/on[^<>=]+=[^<>]*/m', '', $_COOKIE['redirect_page']);
		            $url = preg_replace('/\((.*?)\)/m', '', $redirect_page);
		        }

		    	header("Location: $url");
		    	exit();
		    }
		}
	}
	header("Location: " . PT_Link('wallet'));
	exit();
}


...

 

Link to comment
Share on other sites

:psychic:

There's no logging of errors in here so it's going to be hard to know why something isn't working... They should have been able to confirm that your side was correctly checking the results after they call your site back, so if that's working then I assume the issue is going to be after.

Can you at least see that a transaction has been recorded?

Link to comment
Share on other sites

Many thanks for your reply.

I've looked many places I do not see any notification of a transaction.

Paypal merchant support said they believe the "integration that caused the payment capture call not to be invoked after the customer approved the payment".

Here is the paypal_cofig.php file, maybe this could provide a clue?

$url = "https://api-m.sandbox.paypal.com";
if ($pt->config->paypal_mode == 'live') {
    $url = "https://api-m.paypal.com";
}

$pt->paypal_access_token = null;
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url . '/v1/oauth2/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
curl_setopt($ch, CURLOPT_USERPWD, $pt->config->paypal_id . ':' . $pt->config->paypal_secret);

$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result);
if (!empty($result->access_token)) {
  $pt->paypal_access_token = $result->access_token;
}

I look forward to any guidance

Link to comment
Share on other sites

4 hours ago, Chrisj said:

I've looked many places I do not see any notification of a transaction.

It's not a notification. I'm talking about a record in your [whatever the value of that T_VIDEOS_TRSNS constant is] table.

4 hours ago, Chrisj said:

"integration that caused the payment capture call not to be invoked after the customer approved the payment"

I can't tell for sure but it sounds like the code that handles the callback from PayPal, which I believe is the code starting from

if ($first == 'get_paid') {

Do you have access to server access logs? They would tell you what URLs are being hit on your site - to confirm that this "get_paid" URL (maybe /get_paid/???) is being hit by PayPal, and likely also whether it returned a successful 200 or something else like a 3xx redirect or a 500 error.

Link to comment
Share on other sites

Hi, thanks for your reply.

I don't see any related transaction in video_transactions table.

I don't see anything clearly in server logs.

However, in the paypal.com API Event logs I see, under API Calls, from an attempt today: http status 201, and under debug ID I see Request, and I see Response.

Request shows:

{
  "application_context": {
    "cancel_url": "https://websitename.com/aj/wallet/get_paid?status=false",
    "return_url": "https://websitename.com/aj/wallet/get_paid?status=success&amount=2",
    "shipping_preference": "NO_SHIPPING"
  },
  "intent": "CAPTURE",
  "purchase_units": [
    {
      "amount": {
        "breakdown": {
          "item_total": {
            "currency_code": "USD",
            "value": "2"
          }
        },
        "currency_code": "USD",
        "value": "2"
      },
      "items": [
        {
          "description": "Pay For item",
          "name": "Wallet Replenishment",
          "quantity": "1",
          "unit_amount": {
            "currency_code": "USD",
            "value": "2"
          }
        }
      ]
    }
  ]
}

And Response shows:

{
  "id": "8CV39571RF9321610",
  "links": [
    {
      "href": "https://api.paypal.com/v2/checkout/orders/8CV39571RF9321610",
      "method": "GET",
      "rel": "self"
    },
    {
      "href": "https://www.paypal.com/checkoutnow?token=8CV39571RF9321610",
      "method": "GET",
      "rel": "approve"
    },
    {
      "href": "https://api.paypal.com/v2/checkout/orders/8CV39571RF9321610",
      "method": "PATCH",
      "rel": "update"
    },
    {
      "href": "https://api.paypal.com/v2/checkout/orders/8CV39571RF9321610/capture",
      "method": "POST",
      "rel": "capture"
    }
  ],
  "status": "CREATED"
}

Does this provide any clues?

I look forward to any additional guidance...

 

 

 

 

Link to comment
Share on other sites

5 hours ago, Chrisj said:

However, in the paypal.com API Event logs I see, under API Calls, from an attempt today: http status 201, and under debug ID I see Request, and I see Response.

That's the initial call from your site to PayPal to begin the transaction. What's missing is the second one from PayPal to your site after the transaction has completed.

Do you see anything in your access logs for the URL https://websitename.com/aj/wallet/get_paid and that also includes a token=?

Link to comment
Share on other sites

Much thanks again for your reply.

Upon completion of a live transaction, I see this in 'Webserver SSL transfer log':

 - - [04/May/2023:17:25:53 -0400] "GET /aj/wallet/get_paid?status=success&amount=1.00&token=6H326569M0899450A&PayerID=ZVLJWCX8ST4TS HTTP/2.0" 302 - "https://www.paypal.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"

Does this provide any clues?

I look forward to any additional guidance...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.