Version 4.7.13
This commit is contained in:
1 parent
fd22d99e69
commit
7124a02564
954 files changed
+29277
-59308
No files matched your search
@@ -12,6 +12,9 @@
|
||||
namespace IPS\nexus\Gateway\PayPal;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Settings;
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
@@ -33,9 +36,8 @@ class _Payout extends \IPS\nexus\Payout
|
||||
$settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE );
|
||||
|
||||
$return = array();
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'paypal_api_username', isset( $settings['PayPal'] ) ? $settings['PayPal']['api_username'] : '' );
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'paypal_api_password', isset( $settings['PayPal'] ) ? $settings['PayPal']['api_password'] : '' );
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'paypal_api_signature', isset( $settings['PayPal'] ) ? $settings['PayPal']['api_signature'] : '' );
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'paypal_client_id', ( isset( $settings['PayPal']['client_id'] ) AND isset( $settings['PayPal']['client_id'] ) AND $settings['PayPal']['client_id'] ) ? $settings['PayPal']['client_id'] : '', NULL );
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'paypal_secret', ( isset( $settings['PayPal']['secret'] ) AND $settings['PayPal']['secret'] ) ? $settings['PayPal']['secret'] : '', NULL );
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -77,28 +79,60 @@ class _Payout extends \IPS\nexus\Payout
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
$settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE );
|
||||
|
||||
$response = \IPS\Http\Url::external( \IPS\NEXUS_TEST_GATEWAYS ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp' )->request()->post( array(
|
||||
'METHOD' => 'MassPay',
|
||||
'VERSION' => '90',
|
||||
'USER' => $settings['PayPal']['api_username'],
|
||||
'PWD' => $settings['PayPal']['api_password'],
|
||||
'SIGNATURE' => $settings['PayPal']['api_signature'],
|
||||
'RECEIVERTYPE' => 'EmailAddress',
|
||||
'CURRENCYCODE' => $this->amount->currency,
|
||||
'L_EMAIL0' => $this->data,
|
||||
'L_AMT0' => $this->amount->amountAsString()
|
||||
) )->decodeQueryString();
|
||||
static::checkToken();
|
||||
|
||||
if ( $response['ACK'] != 'Success' )
|
||||
$settings = json_decode( \IPS\Settings::i()->nexus_payout, true );
|
||||
|
||||
$data = array(
|
||||
'items' => array(
|
||||
array(
|
||||
'amount' => array(
|
||||
'currency' => $this->amount->currency,
|
||||
'value' => $this->amount->amountAsString()
|
||||
),
|
||||
'receiver' => $this->data,
|
||||
'recipient_type' => 'EMAIL'
|
||||
)
|
||||
),
|
||||
'sender_batch_header' => array(
|
||||
'recipient_type' => 'EMAIL',
|
||||
'sender_batch_id' => "Payout " . \IPS\DateTime::create()->rfc3339()
|
||||
)
|
||||
);
|
||||
|
||||
$response = \IPS\Http\Url::external( 'https://' . ( \IPS\NEXUS_TEST_GATEWAYS ? 'api-m.sandbox.paypal.com' : 'api.paypal.com' ) . '/v1/payments/payouts' )
|
||||
->request()
|
||||
->forceTls()
|
||||
->setHeaders( array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $settings['PayPal']['token']
|
||||
) )
|
||||
->post( json_encode( $data ) );
|
||||
|
||||
$json = $response->decodeJson();
|
||||
|
||||
if( $response->httpResponseCode != 201 )
|
||||
{
|
||||
throw new \DomainException( $response['L_LONGMESSAGE0'] );
|
||||
throw new \IPS\Http\Request\Exception( $json['message'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->status = static::STATUS_COMPLETE;
|
||||
$this->completed = new \IPS\DateTime;
|
||||
|
||||
if( isset( $json['batch_header'] ) AND $json['batch_header']['payout_batch_id'] )
|
||||
{
|
||||
$this->gw_id = $json['batch_header']['payout_batch_id'];
|
||||
switch( $json['batch_header']['batch_status'] )
|
||||
{
|
||||
case 'DENIED':
|
||||
case 'CANCELED':
|
||||
$this->status = static::STATUS_CANCELED;
|
||||
break;
|
||||
case 'SUCCESS':
|
||||
$this->status = static::STATUS_COMPLETE;
|
||||
break;
|
||||
default:
|
||||
$this->status = static::STATUS_PROCESSING;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
@@ -112,57 +146,167 @@ class _Payout extends \IPS\nexus\Payout
|
||||
*/
|
||||
public static function massProcess( \IPS\Patterns\ActiveRecordIterator $payouts )
|
||||
{
|
||||
/* Make sure we check the token first so that we have proper authorization to API calls */
|
||||
static::checkToken();
|
||||
|
||||
$settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE );
|
||||
|
||||
$byCurrency = array();
|
||||
foreach ( $payouts as $payout )
|
||||
/* Build a batch of payout items */
|
||||
$payoutIds = $payoutData = [];
|
||||
foreach( $payouts as $payout )
|
||||
{
|
||||
$byCurrency[ $payout->amount->currency ][] = array( 'email' => $payout->data, 'amount' => $payout->amount->amountAsString() );
|
||||
$payoutIds[ $payout->amount->currency ] = $payout->id;
|
||||
$payoutData[ $payout->amount->currency ][] = [
|
||||
'amount' => [
|
||||
'currency' => $payout->amount->currency,
|
||||
'value' => $payout->amount->amountAsString()
|
||||
],
|
||||
'receiver' => $payout->data,
|
||||
'recipient_type' => 'EMAIL'
|
||||
];
|
||||
}
|
||||
|
||||
$batches = array();
|
||||
foreach ( $byCurrency as $currency => $recipients )
|
||||
|
||||
foreach( $payoutData as $currency => $batchData )
|
||||
{
|
||||
$baseData = array(
|
||||
'METHOD' => 'MassPay',
|
||||
'VERSION' => '90',
|
||||
'USER' => $settings['PayPal']['api_username'],
|
||||
'PWD' => $settings['PayPal']['api_password'],
|
||||
'SIGNATURE' => $settings['PayPal']['api_signature'],
|
||||
'RECEIVERTYPE' => 'EmailAddress',
|
||||
'CURRENCYCODE' => $currency,
|
||||
);
|
||||
|
||||
$data = $baseData;
|
||||
foreach ( $recipients as $i => $recipient )
|
||||
$requestData = [
|
||||
'items' => $batchData,
|
||||
'sender_batch_header' => [
|
||||
'recipient_type' => 'EMAIL',
|
||||
'sender_batch_id' => "Payout-{$currency}-" . \IPS\DateTime::create()->rfc3339()
|
||||
]
|
||||
];
|
||||
|
||||
$response = \IPS\Http\Url::external( 'https://' . ( \IPS\NEXUS_TEST_GATEWAYS ? 'api-m.sandbox.paypal.com' : 'api.paypal.com' ) . '/v1/payments/payouts' )
|
||||
->request()
|
||||
->forceTls()
|
||||
->setHeaders( [
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $settings['PayPal']['token']
|
||||
] )
|
||||
->post( json_encode( $requestData ) );
|
||||
|
||||
if( $response->httpResponseCode != 201 )
|
||||
{
|
||||
$data["L_EMAIL{$i}"] = $recipient['email'];
|
||||
$data["L_AMT{$i}"] = $recipient['amount'];
|
||||
|
||||
if ( $i >= 249 )
|
||||
throw new \RuntimeException( (string) $response, $response->httpResponseCode );
|
||||
}
|
||||
|
||||
$response = $response->decodeJson();
|
||||
|
||||
if( isset( $response['batch_header'] ) AND $response['batch_header']['payout_batch_id'] )
|
||||
{
|
||||
$update = [
|
||||
'po_gw_id' => $response['batch_header']['payout_batch_id']
|
||||
];
|
||||
|
||||
switch( $response['batch_header']['batch_status'] )
|
||||
{
|
||||
$batches[] = $data;
|
||||
$data = $baseData;
|
||||
case 'DENIED':
|
||||
case 'CANCELED':
|
||||
$update['po_status'] = static::STATUS_CANCELED;
|
||||
break;
|
||||
case 'SUCCESS':
|
||||
$update['po_status'] = static::STATUS_COMPLETE;
|
||||
break;
|
||||
default:
|
||||
$update['po_status'] = static::STATUS_PROCESSING;
|
||||
break;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_payouts', $update, \IPS\Db::i()->in( 'po_id', $payoutIds[ $currency ] ) );
|
||||
}
|
||||
|
||||
$batches[] = $data;
|
||||
}
|
||||
|
||||
$error = NULL;
|
||||
foreach ( $batches as $batchData )
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief cache batch results for further lookup
|
||||
*/
|
||||
protected static array $_batchCache = [];
|
||||
|
||||
/**
|
||||
* Check the status of a payout batch and update the withdrawal requests accordingly
|
||||
*
|
||||
* @param string $batchId
|
||||
* @return string|NULL
|
||||
*/
|
||||
public static function checkStatus( string $batchId ):? string
|
||||
{
|
||||
if( isset( static::$_batchCache[ $batchId ] ) )
|
||||
{
|
||||
$response = \IPS\Http\Url::external( \IPS\NEXUS_TEST_GATEWAYS ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp' )->request()->post( $batchData )->decodeQueryString();
|
||||
|
||||
if ( $response['ACK'] != 'Success' )
|
||||
return static::$_batchCache[ $batchId ];
|
||||
}
|
||||
|
||||
/* Make sure we check the token first so that we have proper authorization to API calls */
|
||||
static::checkToken();
|
||||
|
||||
$settings = json_decode( \IPS\Settings::i()->nexus_payout, TRUE );
|
||||
|
||||
$response = \IPS\Http\Url::external( 'https://' . ( \IPS\NEXUS_TEST_GATEWAYS ? 'api-m.sandbox.paypal.com' : 'api.paypal.com' ) . '/v1/payments/payouts/' . $batchId )
|
||||
->request()
|
||||
->forceTls()
|
||||
->setHeaders( array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $settings['PayPal']['token']
|
||||
) )
|
||||
->get()
|
||||
->decodeJson();
|
||||
|
||||
if( isset( $response['batch_header'] ) AND $response['batch_header']['payout_batch_id'] )
|
||||
{
|
||||
switch( $response['batch_header']['batch_status'] )
|
||||
{
|
||||
$error = $response['L_LONGMESSAGE0'];
|
||||
case 'DENIED':
|
||||
case 'CANCELED':
|
||||
return static::$_batchCache[ $batchId ] = static::STATUS_CANCELED;
|
||||
break;
|
||||
case 'SUCCESS':
|
||||
return static::$_batchCache[ $batchId ] = static::STATUS_COMPLETE;
|
||||
break;
|
||||
default:
|
||||
return static::$_batchCache[ $batchId ] = static::STATUS_PROCESSING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $error )
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Token
|
||||
*
|
||||
* @return void
|
||||
* @throws \IPS\Http\Request\Exception
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
protected static function checkToken()
|
||||
{
|
||||
$payoutSettings = json_decode( \IPS\Settings::i()->nexus_payout, true );
|
||||
$settings = $payoutSettings['PayPal'];
|
||||
|
||||
if ( !isset( $settings['token'] ) or $settings['token_expire'] < time() )
|
||||
{
|
||||
throw new \DomainException( $error );
|
||||
$response = \IPS\Http\Url::external( 'https://' . ( \IPS\NEXUS_TEST_GATEWAYS ? 'api-m.sandbox.paypal.com' : 'api.paypal.com' ) . '/v1/oauth2/token' )
|
||||
->request()
|
||||
->forceTls()
|
||||
->setHeaders( array(
|
||||
'Accept' => 'application/json',
|
||||
'Accept-Language' => 'en_US',
|
||||
) )
|
||||
->login( $settings['client_id'], $settings['secret'] )
|
||||
->post( array( 'grant_type' => 'client_credentials' ) )
|
||||
->decodeJson();
|
||||
|
||||
if ( !isset( $response['access_token'] ) )
|
||||
{
|
||||
throw new \UnexpectedValueException( isset( $response['error_description'] ) ? $response['error_description'] : $response );
|
||||
}
|
||||
|
||||
$settings['token'] = $response['access_token'];
|
||||
$settings['token_expire'] = ( time() + $response['expires_in'] );
|
||||
$payoutSettings['PayPal'] = $settings;
|
||||
|
||||
\IPS\Settings::i()->changeValues( array(
|
||||
'nexus_payout' => json_encode( $payoutSettings )
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user