BraintreeWebhookNotification

The Paid Memberships Pro Braintree WebhookNotification class.

Defined (1)

The class is defined in the following location(s).

/includes/lib/Braintree/lib/Braintree/WebhookNotification.php  
  1. class WebhookNotification extends Base 
  2. const SUBSCRIPTION_CANCELED = 'subscription_canceled'; 
  3. const SUBSCRIPTION_CHARGED_SUCCESSFULLY = 'subscription_charged_successfully'; 
  4. const SUBSCRIPTION_CHARGED_UNSUCCESSFULLY = 'subscription_charged_unsuccessfully'; 
  5. const SUBSCRIPTION_EXPIRED = 'subscription_expired'; 
  6. const SUBSCRIPTION_TRIAL_ENDED = 'subscription_trial_ended'; 
  7. const SUBSCRIPTION_WENT_ACTIVE = 'subscription_went_active'; 
  8. const SUBSCRIPTION_WENT_PAST_DUE = 'subscription_went_past_due'; 
  9. const SUB_MERCHANT_ACCOUNT_APPROVED = 'sub_merchant_account_approved'; 
  10. const SUB_MERCHANT_ACCOUNT_DECLINED = 'sub_merchant_account_declined'; 
  11. const TRANSACTION_DISBURSED = 'transaction_disbursed'; 
  12. const TRANSACTION_SETTLED = 'transaction_settled'; 
  13. const TRANSACTION_SETTLEMENT_DECLINED = 'transaction_settlement_declined'; 
  14. const DISBURSEMENT_EXCEPTION = 'disbursement_exception'; 
  15. const DISBURSEMENT = 'disbursement'; 
  16. const DISPUTE_OPENED = 'dispute_opened'; 
  17. const DISPUTE_LOST = 'dispute_lost'; 
  18. const DISPUTE_WON = 'dispute_won'; 
  19. const PARTNER_MERCHANT_CONNECTED = 'partner_merchant_connected'; 
  20. const PARTNER_MERCHANT_DISCONNECTED = 'partner_merchant_disconnected'; 
  21. const PARTNER_MERCHANT_DECLINED = 'partner_merchant_declined'; 
  22. const CHECK = 'check'; 
  23. const ACCOUNT_UPDATER_DAILY_REPORT = 'account_updater_daily_report'; 
  24.  
  25. public static function parse($signature, $payload) 
  26. if (preg_match("/[^A-Za-z0-9+=\/\n]/", $payload) === 1) { 
  27. throw new Exception\InvalidSignature("payload contains illegal characters"); 
  28.  
  29. Configuration::assertGlobalHasAccessTokenOrKeys(); 
  30. self::_validateSignature($signature, $payload); 
  31.  
  32. $xml = base64_decode($payload); 
  33. $attributes = Xml::buildArrayFromXml($xml); 
  34. return self::factory($attributes['notification']); 
  35.  
  36. public static function verify($challenge) 
  37. if (!preg_match('/^[a-f0-9]{20, 32}$/', $challenge)) { 
  38. throw new Exception\InvalidChallenge("challenge contains non-hex characters"); 
  39. Configuration::assertGlobalHasAccessTokenOrKeys(); 
  40. $publicKey = Configuration::publicKey(); 
  41. $digest = Digest::hexDigestSha1(Configuration::privateKey(), $challenge); 
  42. return "{$publicKey}|{$digest}"; 
  43.  
  44. public static function factory($attributes) 
  45. $instance = new self(); 
  46. $instance->_initialize($attributes); 
  47. return $instance; 
  48.  
  49. private static function _matchingSignature($signaturePairs) 
  50. foreach ($signaturePairs as $pair) 
  51. $components = preg_split("/\|/", $pair); 
  52. if ($components[0] == Configuration::publicKey()) { 
  53. return $components[1]; 
  54.  
  55. return null; 
  56.  
  57. private static function _payloadMatches($signature, $payload) 
  58. $payloadSignature = Digest::hexDigestSha1(Configuration::privateKey(), $payload); 
  59. return Digest::secureCompare($signature, $payloadSignature); 
  60.  
  61. private static function _validateSignature($signatureString, $payload) 
  62. $signaturePairs = preg_split("/&/", $signatureString); 
  63. $signature = self::_matchingSignature($signaturePairs); 
  64. if (!$signature) { 
  65. throw new Exception\InvalidSignature("no matching public key"); 
  66.  
  67. if (!(self::_payloadMatches($signature, $payload) || self::_payloadMatches($signature, $payload . "\n"))) { 
  68. throw new Exception\InvalidSignature("signature does not match payload - one has been modified"); 
  69.  
  70. protected function _initialize($attributes) 
  71. $this->_attributes = $attributes; 
  72.  
  73. if (isset($attributes['subject']['apiErrorResponse'])) { 
  74. $wrapperNode = $attributes['subject']['apiErrorResponse']; 
  75. } else { 
  76. $wrapperNode = $attributes['subject']; 
  77.  
  78. if (isset($wrapperNode['subscription'])) { 
  79. $this->_set('subscription', Subscription::factory($attributes['subject']['subscription'])); 
  80.  
  81. if (isset($wrapperNode['merchantAccount'])) { 
  82. $this->_set('merchantAccount', MerchantAccount::factory($wrapperNode['merchantAccount'])); 
  83.  
  84. if (isset($wrapperNode['transaction'])) { 
  85. $this->_set('transaction', Transaction::factory($wrapperNode['transaction'])); 
  86.  
  87. if (isset($wrapperNode['disbursement'])) { 
  88. $this->_set('disbursement', Disbursement::factory($wrapperNode['disbursement'])); 
  89.  
  90. if (isset($wrapperNode['partnerMerchant'])) { 
  91. $this->_set('partnerMerchant', PartnerMerchant::factory($wrapperNode['partnerMerchant'])); 
  92.  
  93. if (isset($wrapperNode['dispute'])) { 
  94. $this->_set('dispute', Dispute::factory($wrapperNode['dispute'])); 
  95.  
  96. if (isset($wrapperNode['accountUpdaterDailyReport'])) { 
  97. $this->_set('accountUpdaterDailyReport', AccountUpdaterDailyReport::factory($wrapperNode['accountUpdaterDailyReport'])); 
  98.  
  99. if (isset($wrapperNode['errors'])) { 
  100. $this->_set('errors', new Error\ValidationErrorCollection($wrapperNode['errors'])); 
  101. $this->_set('message', $wrapperNode['message']);