如何解决从包创建类的新对象时出现错误
尝试创建新对象时出现此错误
$provider = new ExpressCheckout;
$response = $provider->setExpressCheckout($checkoutData);
我正在使用此软件包https://github.com/srmklive/laravel-paypal将PayPal ExpressCheckout集成到我的Laravel应用中
这是我用来创建对象的Package中的模型。
ExpressCheckout.php
<?php
namespace Srmklive\PayPal\Services;
use Exception;
use Illuminate\Support\Collection;
use Psr\Http\Message\StreamInterface;
use Srmklive\PayPal\Traits\PayPalRequest as PayPalAPIRequest;
use Srmklive\PayPal\Traits\PayPalTransactions;
use Srmklive\PayPal\Traits\RecurringProfiles;
class ExpressCheckout
{
// Integrate PayPal Request trait
use PayPalAPIRequest;
use PayPalTransactions;
use RecurringProfiles;
/**
* ExpressCheckout constructor.
*
* @param array $config
*
* @throws Exception
*/
public function __construct(array $config = [])
{
// Setting PayPal API Credentials
$this->setConfig($config);
$this->httpBodyParam = 'form_params';
$this->options = [];
}
/**
* Set ExpressCheckout API endpoints & options.
*
* @param array $credentials
*
* @return void
*/
public function setExpressCheckoutOptions($credentials)
{
// Setting API Endpoints
if ($this->mode === 'sandbox') {
$this->config['api_url'] = !empty($this->config['secret']) ?
'https://api-3t.sandbox.paypal.com/nvp' : 'https://api.sandbox.paypal.com/nvp';
$this->config['gateway_url'] = 'https://www.sandbox.paypal.com';
$this->config['ipn_url'] = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
} else {
$this->config['api_url'] = !empty($this->config['secret']) ?
'https://api-3t.paypal.com/nvp' : 'https://api.paypal.com/nvp';
$this->config['gateway_url'] = 'https://www.paypal.com';
$this->config['ipn_url'] = 'https://ipnpb.paypal.com/cgi-bin/webscr';
}
// Adding params outside sandbox / live array
$this->config['payment_action'] = $credentials['payment_action'];
$this->config['notify_url'] = $credentials['notify_url'];
$this->config['locale'] = $credentials['locale'];
}
/**
* Set cart item details for PayPal.
*
* @param array $items
*
* @return Collection
*/
protected function setCartItems($items)
{
return (new Collection($items))->map(static function ($item,$num) {
return [
'L_PAYMENTREQUEST_0_NAME'.$num => $item['name'],'L_PAYMENTREQUEST_0_AMT'.$num => $item['price'],'L_PAYMENTREQUEST_0_DESC'.$num => isset($item['desc']) ? $item['desc'] : null,'L_PAYMENTREQUEST_0_QTY'.$num => isset($item['qty']) ? $item['qty'] : 1,];
})->flatMap(static function ($value) {
return $value;
});
}
/**
* Set Recurring payments details for SetExpressCheckout API call.
*
* @param array $data
* @param bool $subscription
*/
protected function setExpressCheckoutRecurringPaymentConfig($data,$subscription = false)
{
$billingType = $this->billingType;
// Overwrite billing type if $subscription flag is enabled
if ($subscription) {
$billingType = 'RecurringPayments';
}
// Send L_BILLINGTYPE0 and L_BILLINGAGREEMENTDESCRIPTION0 only if there is billing type
if (isset($billingType)) {
$this->post = $this->post->merge([
'L_BILLINGTYPE0' => $billingType,'L_BILLINGAGREEMENTDESCRIPTION0' => !empty($data['subscription_desc']) ?
$data['subscription_desc'] : $data['invoice_description'],]);
}
}
/**
* Set item subtotal if available.
*
* @param array $data
*/
protected function setItemSubTotal($data)
{
$this->subtotal = isset($data['subtotal']) ? $data['subtotal'] : $data['total'];
}
/**
* Set shipping amount if available.
*
* @param array $data
*/
protected function setShippingAmount($data)
{
if (isset($data['shipping'])) {
$this->post = $this->post->merge([
'PAYMENTREQUEST_0_SHIPPINGAMT' => $data['shipping'],]);
}
}
/**
* Set tax amount if available.
*
* @param array $data
*/
protected function setTaxAmount($data)
{
if (isset($data['tax'])) {
$this->post = $this->post->merge([
'PAYMENTREQUEST_0_TAXAMT' => $data['tax'],]);
}
}
/**
* Set shipping discount if available.
*
* @param array $data
*/
protected function setShippingDiscount($data)
{
if (isset($data['shipping_discount'])) {
if ($data['shipping_discount'] > 0) {
$data['shipping_discount'] *= -1;
}
$this->post = $this->post->merge([
'PAYMENTREQUEST_0_SHIPDISCAMT' => $data['shipping_discount'],'PAYMENTREQUEST_0_AMT' => round($data['total'] + $data['shipping_discount'],2),]);
}
}
/**
* Perform a SetExpressCheckout API call on PayPal.
*
* @param array $data
* @param bool $subscription
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function setExpressCheckout($data,$subscription = false)
{
$this->setItemSubTotal($data);
$this->post = $this->setCartItems($data['items'])->merge([
'PAYMENTREQUEST_0_ITEMAMT' => $this->subtotal,'PAYMENTREQUEST_0_AMT' => $data['total'],'PAYMENTREQUEST_0_PAYMENTACTION' => $this->paymentAction,'PAYMENTREQUEST_0_CURRENCYCODE' => $this->currency,'PAYMENTREQUEST_0_DESC' => $data['invoice_description'],'PAYMENTREQUEST_0_INVNUM' => $data['invoice_id'],'NOSHIPPING' => 1,'RETURNURL' => $data['return_url'],'CANCELURL' => $data['cancel_url'],'LOCALE' => $this->locale,]);
$this->setTaxAmount($data);
$this->setShippingAmount($data);
$this->setShippingDiscount($data);
$this->setTaxAmount($data);
$this->setExpressCheckoutRecurringPaymentConfig($data,$subscription);
$response = $this->doPayPalRequest('SetExpressCheckout');
return collect($response)->merge([
'paypal_link' => !empty($response['TOKEN']) ? $this->config['gateway_url'].'/webscr?cmd=_express-checkout&token='.$response['TOKEN'] : null,])->toArray();
}
/**
* Perform a GetExpressCheckoutDetails API call on PayPal.
*
* @param string $token
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function getExpressCheckoutDetails($token)
{
$this->setRequestData([
'TOKEN' => $token,]);
return $this->doPayPalRequest('GetExpressCheckoutDetails');
}
/**
* Perform DoExpressCheckoutPayment API call on PayPal.
*
* @param array $data
* @param string $token
* @param string $payerId
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function doExpressCheckoutPayment($data,$token,$payerId)
{
$this->setItemSubTotal($data);
$this->post = $this->setCartItems($data['items'])->merge([
'TOKEN' => $token,'PAYERID' => $payerId,'PAYMENTREQUEST_0_ITEMAMT' => $this->subtotal,'PAYMENTREQUEST_0_PAYMENTACTION' => !empty($this->config['payment_action']) ? $this->config['payment_action'] : 'Sale','PAYMENTREQUEST_0_NOTIFYURL' => $this->notifyUrl,]);
$this->setTaxAmount($data);
$this->setShippingAmount($data);
return $this->doPayPalRequest('DoExpressCheckoutPayment');
}
/**
* Perform a DoAuthorization API call on PayPal.
*
* @param string $authorizationId Transaction ID
* @param float $amount Amount to capture
* @param array $data Optional request fields
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function doAuthorization($authorizationId,$amount,$data = [])
{
$this->setRequestData(
array_merge($data,[
'AUTHORIZATIONID' => $authorizationId,'AMT' => $amount,])
);
return $this->doPayPalRequest('DoAuthorization');
}
/**
* Perform a DoCapture API call on PayPal.
*
* @param string $authorizationId Transaction ID
* @param float $amount Amount to capture
* @param string $complete Indicates whether or not this is the last capture.
* @param array $data Optional request fields
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function doCapture($authorizationId,$complete = 'Complete','COMPLETETYPE' => $complete,'CURRENCYCODE' => $this->currency,])
);
return $this->doPayPalRequest('DoCapture');
}
/**
* Perform a DoReauthorization API call on PayPal to reauthorize an existing authorization transaction.
*
* @param string $authorizationId
* @param float $amount
* @param array $data
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function doReAuthorization($authorizationId,'AMOUNT' => $amount,])
);
return $this->doPayPalRequest('DoReauthorization');
}
/**
* Perform a DoVoid API call on PayPal.
*
* @param string $authorizationId Transaction ID
* @param array $data Optional request fields
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function doVoid($authorizationId,])
);
return $this->doPayPalRequest('DoVoid');
}
/**
* Perform a CreateBillingAgreement API call on PayPal.
*
* @param string $token
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function createBillingAgreement($token)
{
$this->setRequestData([
'TOKEN' => $token,]);
return $this->doPayPalRequest('CreateBillingAgreement');
}
/**
* Perform a CreateRecurringPaymentsProfile API call on PayPal.
*
* @param array $data
* @param string $token
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function createRecurringPaymentsProfile($data,$token)
{
$this->post = $this->setRequestData($data)->merge([
'TOKEN' => $token,]);
return $this->doPayPalRequest('CreateRecurringPaymentsProfile');
}
/**
* Perform a GetRecurringPaymentsProfileDetails API call on PayPal.
*
* @param string $id
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function getRecurringPaymentsProfileDetails($id)
{
$this->setRequestData([
'PROFILEID' => $id,]);
return $this->doPayPalRequest('GetRecurringPaymentsProfileDetails');
}
/**
* Perform a UpdateRecurringPaymentsProfile API call on PayPal.
*
* @param array $data
* @param string $id
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function updateRecurringPaymentsProfile($data,$id)
{
$this->post = $this->setRequestData($data)->merge([
'PROFILEID' => $id,]);
return $this->doPayPalRequest('UpdateRecurringPaymentsProfile');
}
/**
* Change Recurring payment profile status on PayPal.
*
* @param string $id
* @param string $status
*
* @throws Exception
*
* @return array|StreamInterface
*/
protected function manageRecurringPaymentsProfileStatus($id,$status)
{
$this->setRequestData([
'PROFILEID' => $id,'ACTION' => $status,]);
return $this->doPayPalRequest('ManageRecurringPaymentsProfileStatus');
}
/**
* Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to cancel a RecurringPaymentsProfile.
*
* @param string $id
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function cancelRecurringPaymentsProfile($id)
{
return $this->manageRecurringPaymentsProfileStatus($id,'Cancel');
}
/**
* Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to suspend a RecurringPaymentsProfile.
*
* @param string $id
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function suspendRecurringPaymentsProfile($id)
{
return $this->manageRecurringPaymentsProfileStatus($id,'Suspend');
}
/**
* Perform a ManageRecurringPaymentsProfileStatus API call on PayPal to reactivate a RecurringPaymentsProfile.
*
* @param string $id
*
* @throws Exception
*
* @return array|StreamInterface
*/
public function reactivateRecurringPaymentsProfile($id)
{
return $this->manageRecurringPaymentsProfileStatus($id,'Reactivate');
}
}
PayPalRequest.php
<?php
namespace Srmklive\PayPal\Traits;
use Exception;
use GuzzleHttp\Client as HttpClient;
use Illuminate\Support\Collection;
use Psr\Http\Message\StreamInterface;
use RuntimeException;
use Srmklive\PayPal\Services\AdaptivePayments;
use Srmklive\PayPal\Services\ExpressCheckout;
trait PayPalRequest
{
use PayPalHttpClient;
/**
* Http Client class object.
*
* @var HttpClient
*/
private $client;
/**
* Http Client configuration.
*
* @var array
*/
private $httpClientConfig;
/**
* PayPal API Certificate data for authentication.
*
* @var string
*/
private $certificate;
/**
* PayPal API mode to be used.
*
* @var string
*/
public $mode;
/**
* Request data to be sent to PayPal.
*
* @var Collection
*/
protected $post;
/**
* PayPal API configuration.
*
* @var array
*/
private $config;
/**
* Item subtotal.
*
* @var float
*/
private $subtotal;
/**
* Default currency for PayPal.
*
* @var string
*/
private $currency;
/**
* Default billing type for PayPal reference transactions.
*
* @var string
*/
private $billingType;
/**
* Additional options for PayPal API request.
*
* @var array
*/
private $options;
/**
* Default payment action for PayPal.
*
* @var string
*/
private $paymentAction;
/**
* Default locale for PayPal.
*
* @var string
*/
private $locale;
/**
* PayPal API Endpoint.
*
* @var string
*/
private $apiUrl;
/**
* IPN notification url for PayPal.
*
* @var string
*/
private $notifyUrl;
/**
* Http Client request body parameter name.
*
* @var string
*/
private $httpBodyParam;
/**
* Validate SSL details when creating HTTP client.
*
* @var bool
*/
private $validateSSL;
/**
* Set PayPal API Credentials.
*
* @param array $credentials
*
* @throws Exception
*
* @return void
*/
public function setApiCredentials($credentials)
{
// Setting Default PayPal Mode If not set
$this->setApiEnvironment($credentials);
// Set API configuration for the PayPal provider
$this->setApiProviderConfiguration($credentials);
// Set default currency.
$this->setCurrency($credentials['currency']);
// Set default billing type
$this->setBillingType($credentials['billing_type']);
// Set Http Client configuration.
$this->setHttpClientConfiguration();
}
/**
* Set other/override PayPal API parameters.
*
* @param array $options
*
* @return $this
*/
public function addOptions(array $options)
{
$this->options = $options;
return $this;
}
/**
* Function to set currency.
*
* @param string $currency
*
* @throws Exception
*
* @return $this
*/
public function setCurrency($currency = 'USD')
{
$allowedCurrencies = ['AUD','BRL','CAD','CZK','DKK','EUR','HKD','HUF','ILS','INR','JPY','MYR','MXN','NOK','NZD','PHP','PLN','GBP','SGD','SEK','CHF','TWD','THB','USD','RUB'];
// Check if provided currency is valid.
if (!in_array($currency,$allowedCurrencies,true)) {
throw new Exception('Currency is not supported by PayPal.');
}
$this->currency = $currency;
return $this;
}
/**
* Function to set billing type.
*
* @param string $billingType
*
* @throws Exception
*
* @return $this
*/
public function setBillingType($billingType = 'MerchantInitiatedBilling')
{
$allowedBillingTypes = ['MerchantInitiatedBilling','MerchantInitiatedBillingSingleAgreement','RecurringPayments'];
if ($billingType !== null && !in_array($billingType,$allowedBillingTypes,true)) {
throw new RuntimeException('Billing type is not supported by PayPal.');
}
$this->billingType = $billingType;
return $this;
}
/**
* Retrieve PayPal IPN Response.
*
* @param array $post
*
* @throws Exception
*
* @return array
*/
public function verifyIPN($post)
{
$this->setRequestData($post);
$this->apiUrl = $this->config['ipn_url'];
return $this->doPayPalRequest('verifyipn');
}
/**
* Setup request data to be sent to PayPal.
*
* @param array $data
*
* @return Collection
*/
protected function setRequestData(array $data = [])
{
if (($this->post instanceof Collection) && (!$this->post->isEmpty())) {
unset($this->post);
}
$this->post = new Collection($data);
return $this->post;
}
/**
* Function To Set PayPal API Configuration.
*
* @param array $config
*
* @throws Exception
*/
private function setConfig(array $config = [])
{
// Set Api Credentials
if (function_exists('config')) {
$this->setApiCredentials(
config('paypal')
);
} elseif (!empty($config)) {
$this->setApiCredentials($config);
}
$this->setRequestData();
}
/**
* Set default values for configuration.
*
* @return void
*/
private function setDefaultValues()
{
// Set default payment action.
if (empty($this->paymentAction)) {
$this->paymentAction = 'Sale';
}
// Set default locale.
if (empty($this->locale)) {
$this->locale = 'en_US';
}
// Set default value for SSL validation.
if (empty($this->validateSSL)) {
$this->validateSSL = false;
}
}
/**
* Set API environment to be used by PayPal.
*
* @param array $credentials
*
* @return void
*/
private function setApiEnvironment($credentials)
{
if (empty($credentials['mode']) || !in_array($credentials['mode'],['sandbox','live'])) {
$this->mode = 'live';
} else {
$this->mode = $credentials['mode'];
}
}
/**
* Set configuration details for the provider.
*
* @param array $credentials
*
* @throws Exception
*
* @return void
*/
private function setApiProviderConfiguration($credentials)
{
// Setting PayPal API Credentials
collect($credentials[$this->mode])->map(function ($value,$key) {
$this->config[$key] = $value;
});
// Setup PayPal API Signature value to use.
$this->config['signature'] = empty($this->config['certificate']) ?
$this->config['secret'] : $this->config['certificate'];
$this->paymentAction = $credentials['payment_action'];
$this->locale = $credentials['locale'];
$this->certificate = $this->config['certificate'];
$this->validateSSL = $credentials['validate_ssl'];
$this->setApiProvider($credentials);
}
/**
* Determines which API provider should be used.
*
* @param array $credentials
*
* @throws Exception
*/
private function setApiProvider($credentials)
{
if ($this instanceof AdaptivePayments) {
return $this->setAdaptivePaymentsOptions();
}
if ($this instanceof ExpressCheckout) {
return $this->setExpressCheckoutOptions($credentials);
}
throw new RuntimeException('Invalid api credentials provided for PayPal!. Please provide the right api credentials.');
}
/**
* Create request payload to be sent to PayPal.
*
* @param string $method
*/
private function createRequestPayload($method)
{
$config = array_merge([
'USER' => $this->config['username'],'PWD' => $this->config['password'],'SIGNATURE' => $this->config['signature'],'VERSION' => 123,'METHOD' => $method,],$this->options);
$this->post = $this->post->merge($config);
if ($method === 'verifyipn') {
$this->post->forget('METHOD');
}
}
/**
* Parse PayPal NVP Response.
*
* @param string $method
* @param array|StreamInterface $response
*
* @return array
*/
private function retrieveData($method,$response)
{
if ($method === 'verifyipn') {
return $response;
}
parse_str($response,$output);
return $output;
}
}
错误消息
ErrorException试图访问类型为null的值的数组偏移量
解决方法
尝试运行这些命令
composer update
php artisan cache:clear
php artisan config:clear
php artisan view:clear
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。