i use the latest v2 paypal php sdk sandbox and samples with laravel framework, the create order always success but when capture the order it always fails
and return this error:
"{"name":"UNPROCESSABLE_ENTITY",
"details":[
{"issue":"COMPLIANCE_VIOLATION",
"description":"Transaction cannot be processed due to a possible compliance violation. To get more information about the transaction, call Customer Support."}],
"message":"The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id":"d701744348160",
"links":[{"href":"https://developer.paypal.com/docs/api/orders/v2/#error-COMPLIANCE_VIOLATION","rel":"information_link","method":"GET"}]}
my web.php file :
Route::get('capture_order', 'PayController@capture_order')->name('capture_order');
Route::get('create_order', 'PayController@create_order')->name('create_order');
Route::get('cancel', 'PayController@cancel')->name('payment.cancel');
Route::get('return', 'PayController@return')->name('payment.return');
Route::get('success', 'PayController@success')->name('payment.success');
& the PayController :
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use PayPalCheckoutSdkCorePayPalHttpClient;
use PayPalCheckoutSdkCoreSandboxEnvironment;
use PayPalCheckoutSdkOrdersOrdersCreateRequest;
use PayPalCheckoutSdkOrdersOrdersCaptureRequest;
class PayController extends Controller
{
public $clientId;
public $clientSecret;
public $client;
public $cancel_url = 'http://localhost:8000/cancel';
public $return_url = 'http://localhost:8000/return';
public function __construct()
{
$mode = config('paypal.mode', 'sandbox');
if ($mode == "live") {
$this->clientId = config('paypal.live.client_id');
$this->clientSecret = config('paypal.live.client_secret');
} else {
$this->clientId = config('paypal.sandbox.client_id');
$this->clientSecret = config('paypal.sandbox.client_secret');
}
$environment = new SandboxEnvironment($this->clientId, $this->clientSecret);
$this->client = new PayPalHttpClient($environment);
}
private function buildRequestBody()
{
return [
'intent' => 'CAPTURE',
'application_context' =>[ "cancel_url" => $this->cancel_url,
"return_url" => $this->return_url],
'purchase_units' =>
[
0 => [
'amount' =>
[
'currency_code' => 'USD',
'value' => '20'
]
]
]
];
}
public function create_order()
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = $this->buildRequestBody();
try {
$response = $this->client->execute($request);
foreach ($response->result->links as $key => $value) {
if ($value->rel == "approve")
{
return redirect($value->href);
}
}
}catch (Exception $ex) {
echo $ex->statusCode;
print_r($ex->getMessage());
}
}
public function capture_order(Request $request)
{
// if ($request->token) {
$request = new OrdersCaptureRequest($request->token);
$request->prefer('return=representation');
try {
$response = $this->client->execute($request);
}catch (Exception $ex) {
echo $ex->statusCode;
dd($ex->getMessage());
}
// }
}
/**
* Responds with a welcome message with instructions
*
* @return IlluminateHttpResponse
*/
public function cancel(Request $request)
{
dump($request->all());
dd('Your payment is canceled. You can create cancel page here.');
}
/**
* Responds with a welcome message with instructions
*
* @return IlluminateHttpResponse
*/
public function return(Request $request)
{
if ($request->token) {
return redirect()->route('capture_order', [
'token' => $request->token,
'PayerID' => $request->PayerID
]);
}
dd($request->all());
}
}
i use paypal php sdk with a sandbox account.
2
Answers
i call the support and the response was:
Funds received into Egyptian accounts need to be automatically withdrawn to an attached funding source, such as a bank. You can set this up by going into the account settings section of the account, then the "money, banks and cards" section and at the bottom of that page you'll find "automatic withdrawal" where you can specify a financial instrument to use for automatic withdrawals -- https://www.sandbox.paypal.com/businessmanage/account/money
thanks for u all :)
This problem is most likely related to the country of the receiving sandbox Business account. Create a new account for a different country such as US, then create a new REST app that uses that sandbox account, and test its sandbox clientid/secret in sandbox mode instead.
For later use in live mode, ensure that if the live business account is from one of the countries that require it, that the live account has a valid auto sweep withdrawal method active and enabled on the account, such as a US bank or local visa card. If you need help configuring auto sweep for live mode, contact PayPal’s business support