class PayPalWebsitePaymentsPro in Ubercart 8.4
Defines the PayPal Website Payments Pro payment method.
Plugin annotation
@UbercartPaymentMethod(
id = "paypal_wpp",
name = @Translation("PayPal Website Payments Pro"),
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\uc_payment\PaymentMethodPluginBase implements ContainerFactoryPluginInterface, PaymentMethodPluginInterface
- class \Drupal\uc_credit\CreditCardPaymentMethodBase
- class \Drupal\uc_paypal\Plugin\Ubercart\PaymentMethod\PayPalWebsitePaymentsPro
- class \Drupal\uc_credit\CreditCardPaymentMethodBase
- class \Drupal\uc_payment\PaymentMethodPluginBase implements ContainerFactoryPluginInterface, PaymentMethodPluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of PayPalWebsitePaymentsPro
File
- payment/
uc_paypal/ src/ Plugin/ Ubercart/ PaymentMethod/ PayPalWebsitePaymentsPro.php, line 21
Namespace
Drupal\uc_paypal\Plugin\Ubercart\PaymentMethodView source
class PayPalWebsitePaymentsPro extends CreditCardPaymentMethodBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'wps_email' => '',
'wpp_server' => 'https://api-3t.sandbox.paypal.com/nvp',
'api' => [
'api_username' => '',
'api_password' => '',
'api_signature' => '',
],
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['wps_email'] = [
'#type' => 'email',
'#title' => $this
->t('PayPal e-mail address'),
'#description' => $this
->t('The e-mail address you use for the PayPal account you want to receive payments.'),
'#default_value' => $this->configuration['wps_email'],
];
$form['wpp_server'] = [
'#type' => 'select',
'#title' => $this
->t('API server'),
'#description' => $this
->t('Sign up for and use a Sandbox account for testing.'),
'#options' => [
'https://api-3t.sandbox.paypal.com/nvp' => $this
->t('Sandbox'),
'https://api-3t.paypal.com/nvp' => $this
->t('Live'),
],
'#default_value' => $this->configuration['wpp_server'],
];
$form['api'] = [
'#type' => 'details',
'#title' => $this
->t('API credentials'),
'#description' => $this
->t('@link for information on obtaining credentials. You need to acquire an API Signature. If you have already requested API credentials, you can review your settings under the API Access section of your PayPal profile.', [
'@link' => Link::fromTextAndUrl($this
->t('Click here'), Url::fromUri('https://developer.paypal.com/docs/classic/api/apiCredentials/'))
->toString(),
]),
'#open' => TRUE,
];
$form['api']['api_username'] = [
'#type' => 'textfield',
'#title' => $this
->t('API username'),
'#default_value' => $this->configuration['api']['api_username'],
];
$form['api']['api_password'] = [
'#type' => 'textfield',
'#title' => $this
->t('API password'),
'#default_value' => $this->configuration['api']['api_password'],
];
$form['api']['api_signature'] = [
'#type' => 'textfield',
'#title' => $this
->t('Signature'),
'#default_value' => $this->configuration['api']['api_signature'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['wps_email'] = trim($form_state
->getValue('wps_email'));
$this->configuration['wpp_server'] = $form_state
->getValue('wpp_server');
$this->configuration['api']['api_username'] = $form_state
->getValue([
'settings',
'api',
'api_username',
]);
$this->configuration['api']['api_password'] = $form_state
->getValue([
'settings',
'api',
'api_password',
]);
$this->configuration['api']['api_signature'] = $form_state
->getValue([
'settings',
'api',
'api_signature',
]);
}
/**
* {@inheritdoc}
*/
protected function chargeCard(OrderInterface $order, $amount, $txn_type, $reference = NULL) {
if ($txn_type == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
$nvp_request = [
'METHOD' => 'DoCapture',
'AUTHORIZATIONID' => $reference,
'AMT' => uc_currency_format($amount, FALSE, FALSE, '.'),
'CURRENCYCODE' => $order
->getCurrency(),
'COMPLETETYPE' => 'Complete',
];
}
else {
if (intval($order->payment_details['cc_exp_month']) < 10) {
$expdate = '0' . $order->payment_details['cc_exp_month'] . $order->payment_details['cc_exp_year'];
}
else {
$expdate = $order->payment_details['cc_exp_month'] . $order->payment_details['cc_exp_year'];
}
$cc_type = NULL;
if (isset($order->payment_details['cc_type'])) {
switch (strtolower($order->payment_details['cc_type'])) {
case 'amex':
case 'american express':
$cc_type = 'Amex';
break;
case 'visa':
$cc_type = 'Visa';
break;
case 'mastercard':
case 'master card':
$cc_type = 'MasterCard';
break;
case 'discover':
$cc_type = 'Discover';
break;
}
}
if (is_null($cc_type)) {
$cc_type = $this
->cardType($order->payment_details['cc_number']);
if ($cc_type === FALSE) {
$this
->messenger()
->addError($this
->t('The credit card type did not pass validation.'));
\Drupal::logger('uc_paypal')
->error('Could not figure out cc type: @number / @type', [
'@number' => $order->payment_details['cc_number'],
'@type' => $order->payment_details['cc_type'],
]);
return [
'success' => FALSE,
];
}
}
// PayPal doesn't accept IPv6 addresses.
$ip_address = ltrim(\Drupal::request()
->getClientIp(), '::ffff:');
$address = $order
->getAddress('billing');
$nvp_request = [
'METHOD' => 'DoDirectPayment',
'PAYMENTACTION' => $txn_type == UC_CREDIT_AUTH_ONLY ? 'Authorization' : 'Sale',
'IPADDRESS' => $ip_address,
'AMT' => uc_currency_format($amount, FALSE, FALSE, '.'),
'CREDITCARDTYPE' => $cc_type,
'ACCT' => $order->payment_details['cc_number'],
'EXPDATE' => $expdate,
'CVV2' => $order->payment_details['cc_cvv'],
'FIRSTNAME' => substr($address
->getFirstName(), 0, 25),
'LASTNAME' => substr($address
->getLastName(), 0, 25),
'STREET' => substr($address
->getStreet1(), 0, 100),
'STREET2' => substr($address
->getStreet2(), 0, 100),
'CITY' => substr($address
->getCity(), 0, 40),
'STATE' => $address
->getZone(),
'ZIP' => $address
->getPostalCode(),
'COUNTRYCODE' => $address
->getCountry(),
'CURRENCYCODE' => $order
->getCurrency(),
'DESC' => $this
->t('Order @order_id at @store', [
'@order_id' => $order
->id(),
'@store' => uc_store_name(),
]),
'INVNUM' => $order
->id() . '-' . REQUEST_TIME,
'BUTTONSOURCE' => 'Ubercart_ShoppingCart_DP_US',
'NOTIFYURL' => Url::fromRoute('uc_paypal.ipn', [], [
'absolute' => TRUE,
])
->toString(),
'EMAIL' => substr($order
->getEmail(), 0, 127),
'PHONENUM' => substr($address
->getPhone(), 0, 20),
];
if ($order
->isShippable()) {
$address = $order
->getAddress('delivery');
$nvp_request += [
'SHIPTONAME' => substr($address
->getFirstName() . ' ' . $address
->getLastName(), 0, 25),
'SHIPTOSTREET' => substr($address
->getStreet1(), 0, 100),
'SHIPTOSTREET2' => substr($address
->getStreet2(), 0, 100),
'SHIPTOCITY' => substr($address
->getCity(), 0, 40),
'SHIPTOSTATE' => $address
->getZone(),
'SHIPTOZIP' => $address
->getPostalCode(),
'SHIPTOCOUNTRYCODE' => $address
->getCountry(),
];
}
}
$nvp_response = $this
->sendNvpRequest($nvp_request);
$types = uc_credit_transaction_types();
switch ($nvp_response['ACK']) {
case 'SuccessWithWarning':
\Drupal::logger('uc_paypal')
->warning('<b>@type succeeded with a warning.</b>@paypal_message', [
'@paypal_message' => $this
->buildErrorMessages($nvp_response),
'@type' => $types[$txn_type],
'link' => $order
->toLink($this
->t('view order'))
->toString(),
]);
// Fall through.
case 'Success':
$message = $this
->t('<b>@type</b><br /><b>Success: </b>@amount @currency', [
'@type' => $types[$txn_type],
'@amount' => uc_currency_format($nvp_response['AMT'], FALSE),
'@currency' => $nvp_response['CURRENCYCODE'],
]);
if ($txn_type != UC_CREDIT_PRIOR_AUTH_CAPTURE) {
$message .= '<br />' . $this
->t('<b>Address:</b> @avscode', [
'@avscode' => $this
->avscodeMessage($nvp_response['AVSCODE']),
]);
$message .= '<br />' . $this
->t('<b>CVV2:</b> @cvvmatch', [
'@cvvmatch' => $this
->cvvmatchMessage($nvp_response['CVV2MATCH']),
]);
}
$result = [
'success' => TRUE,
'comment' => $this
->t('PayPal transaction ID: @transactionid', [
'@transactionid' => $nvp_response['TRANSACTIONID'],
]),
'message' => $message,
'data' => [
'module' => 'uc_paypal',
'txn_id' => (string) SafeMarkup::checkPlain($nvp_response['TRANSACTIONID']),
],
'uid' => \Drupal::currentUser()
->id(),
];
// If this was an authorization only transaction...
if ($txn_type == UC_CREDIT_AUTH_ONLY) {
// Log the authorization to the order.
uc_credit_log_authorization($order
->id(), $nvp_response['TRANSACTIONID'], $nvp_response['AMT']);
}
elseif ($txn_type == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
uc_credit_log_prior_auth_capture($order
->id(), $reference);
}
// Log the IPN to the database.
$this->database
->insert('uc_payment_paypal_ipn')
->fields([
'order_id' => $order
->id(),
'txn_id' => $nvp_response['TRANSACTIONID'],
'txn_type' => 'web_accept',
'mc_gross' => $amount,
'status' => 'Completed',
'payer_email' => $order
->getEmail(),
'received' => REQUEST_TIME,
])
->execute();
break;
case 'FailureWithWarning':
// Fall through.
case 'Failure':
$message = $this
->t('<b>@type failed.</b>', [
'@type' => $types[$txn_type],
]) . $this
->buildErrorMessages($nvp_response);
$result = [
'success' => FALSE,
'message' => $message,
'uid' => \Drupal::currentUser()
->id(),
];
break;
default:
$message = $this
->t('Unexpected acknowledgement status: @status', [
'@status' => $nvp_response['ACK'],
]);
$result = [
'success' => NULL,
'message' => $message,
'uid' => \Drupal::currentUser()
->id(),
];
break;
}
uc_order_comment_save($order
->id(), \Drupal::currentUser()
->id(), $message, 'admin');
// Don't log this as a payment money wasn't actually captured.
if (in_array($txn_type, [
UC_CREDIT_AUTH_ONLY,
])) {
$result['log_payment'] = FALSE;
}
return $result;
}
/**
* Sends a request to the PayPal NVP API.
*/
public function sendNvpRequest($params) {
$host = $this->configuration['wpp_server'];
$params += [
'USER' => $this->configuration['api']['api_username'],
'PWD' => $this->configuration['api']['api_password'],
'SIGNATURE' => $this->configuration['api']['api_signature'],
'VERSION' => '3.0',
];
try {
$response = \Drupal::httpClient()
->request('POST', $host, [
'form_params' => $params,
]);
parse_str($response
->getBody(), $output);
return $output;
} catch (TransferException $e) {
\Drupal::logger('uc_paypal')
->error('NVP API request failed with HTTP error %error.', [
'%error' => $e
->getMessage(),
]);
}
}
/**
* Builds error message(s) from PayPal failure responses.
*/
protected function buildErrorMessages($nvp_response) {
$code = 0;
$message = '';
while (array_key_exists('L_SEVERITYCODE' . $code, $nvp_response)) {
$message .= '<br /><b>' . SafeMarkup::checkPlain($nvp_response['L_SEVERITYCODE' . $code]) . ':</b> ' . SafeMarkup::checkPlain($nvp_response['L_ERRORCODE' . $code]) . ': ' . SafeMarkup::checkPlain($nvp_response['L_LONGMESSAGE' . $code]);
$code++;
}
return $message;
}
/**
* Returns the PayPal approved credit card type for a card number.
*/
protected function cardType($cc_number) {
switch (substr(strval($cc_number), 0, 1)) {
case '3':
return 'Amex';
case '4':
return 'Visa';
case '5':
return 'MasterCard';
case '6':
return 'Discover';
}
return FALSE;
}
/**
* Returns a human readable message for the AVS code.
*/
protected function avscodeMessage($code) {
if (is_numeric($code)) {
switch ($code) {
case '0':
return $this
->t('All the address information matched.');
case '1':
return $this
->t('None of the address information matched; transaction declined.');
case '2':
return $this
->t('Part of the address information matched.');
case '3':
return $this
->t('The merchant did not provide AVS information. Not processed.');
case '4':
return $this
->t('Address not checked, or acquirer had no response. Service not available.');
default:
return $this
->t('No AVS response was obtained.');
}
}
switch ($code) {
case 'A':
case 'B':
return $this
->t('Address matched; postal code did not');
case 'C':
case 'N':
return $this
->t('Nothing matched; transaction declined');
case 'D':
case 'F':
case 'X':
case 'Y':
return $this
->t('Address and postal code matched');
case 'E':
return $this
->t('Not allowed for MOTO transactions; transaction declined');
case 'G':
return $this
->t('Global unavailable');
case 'I':
return $this
->t('International unavailable');
case 'P':
case 'W':
case 'Z':
return $this
->t('Postal code matched; address did not');
case 'R':
return $this
->t('Retry for validation');
case 'S':
return $this
->t('Service not supported');
case 'U':
return $this
->t('Unavailable');
case 'Null':
return $this
->t('No AVS response was obtained.');
default:
return $this
->t('An unknown error occurred.');
}
}
/**
* Returns a human readable message for the CVV2 match code.
*/
protected function cvvmatchMessage($code) {
if (is_numeric($code)) {
switch ($code) {
case '0':
return $this
->t('Matched');
case '1':
return $this
->t('No match');
case '2':
return $this
->t('The merchant has not implemented CVV2 code handling.');
case '3':
return $this
->t('Merchant has indicated that CVV2 is not present on card.');
case '4':
return $this
->t('Service not available');
default:
return $this
->t('Unkown error');
}
}
switch ($code) {
case 'M':
return $this
->t('Match');
case 'N':
return $this
->t('No match');
case 'P':
return $this
->t('Not processed');
case 'S':
return $this
->t('Service not supported');
case 'U':
return $this
->t('Service not available');
case 'X':
return $this
->t('No response');
default:
return $this
->t('Not checked');
}
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CreditCardPaymentMethodBase:: |
public | function |
Returns the form or render array to be displayed at checkout. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when checkout is submitted with this payment method selected. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Returns the payment method review details. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Returns the payment method title to be used on the checkout review page. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being viewed by a customer. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
protected | function | Returns a credit card number with appropriate masking. | |
CreditCardPaymentMethodBase:: |
public | function |
Returns the payment method label with logo. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function | Returns the set of fields which are used by this payment method. | |
CreditCardPaymentMethodBase:: |
public | function | Returns the set of card types which are used by this payment method. | |
CreditCardPaymentMethodBase:: |
public | function | Returns the set of transaction types allowed by this payment method. | 1 |
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being edited with this payment method. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being loaded with this payment method. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being saved with this payment method. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being submitted with this payment method. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function |
Called when an order is being viewed by an administrator. Overrides PaymentMethodPluginBase:: |
|
CreditCardPaymentMethodBase:: |
public | function | Process a payment through the credit card gateway. | |
CreditCardPaymentMethodBase:: |
protected | function | Validates a credit card number during checkout. | |
CreditCardPaymentMethodBase:: |
protected | function | Validates a CVV number during checkout. | |
CreditCardPaymentMethodBase:: |
protected | function | Validates an expiration date on a card. | |
CreditCardPaymentMethodBase:: |
protected | function | Validates an issue number on a card. | |
CreditCardPaymentMethodBase:: |
protected | function | Validates a start date on a card. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PaymentMethodPluginBase:: |
protected | property | The database service. | |
PaymentMethodPluginBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
PaymentMethodPluginBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
PaymentMethodPluginBase:: |
public | function |
Called when an order is being deleted. Overrides PaymentMethodPluginInterface:: |
1 |
PaymentMethodPluginBase:: |
public | function |
Called when an order is being submitted after being edited. Overrides PaymentMethodPluginInterface:: |
1 |
PaymentMethodPluginBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
|
PaymentMethodPluginBase:: |
public | function |
Form validation handler. Overrides PluginFormInterface:: |
|
PaymentMethodPluginBase:: |
public | function |
Constructs the PaymentMethodPluginBase object. Overrides PluginBase:: |
|
PayPalWebsitePaymentsPro:: |
protected | function | Returns a human readable message for the AVS code. | |
PayPalWebsitePaymentsPro:: |
public | function |
Form constructor. Overrides CreditCardPaymentMethodBase:: |
|
PayPalWebsitePaymentsPro:: |
protected | function | Builds error message(s) from PayPal failure responses. | |
PayPalWebsitePaymentsPro:: |
protected | function | Returns the PayPal approved credit card type for a card number. | |
PayPalWebsitePaymentsPro:: |
protected | function |
Called when a credit card should be processed. Overrides CreditCardPaymentMethodBase:: |
|
PayPalWebsitePaymentsPro:: |
protected | function | Returns a human readable message for the CVV2 match code. | |
PayPalWebsitePaymentsPro:: |
public | function |
Gets default configuration for this plugin. Overrides CreditCardPaymentMethodBase:: |
|
PayPalWebsitePaymentsPro:: |
public | function | Sends a request to the PayPal NVP API. | |
PayPalWebsitePaymentsPro:: |
public | function |
Form submission handler. Overrides CreditCardPaymentMethodBase:: |
|
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |