Overview

Classes

  • Syspay_Merchant_AstroPayBanksRequest
  • Syspay_Merchant_BillingAgreementCancellationRequest
  • Syspay_Merchant_BillingAgreementInfoRequest
  • Syspay_Merchant_BillingAgreementListRequest
  • Syspay_Merchant_BillingAgreementRequest
  • Syspay_Merchant_ChargebackInfoRequest
  • Syspay_Merchant_ChargebackListRequest
  • Syspay_Merchant_Client
  • Syspay_Merchant_ConfirmRequest
  • Syspay_Merchant_EMS
  • Syspay_Merchant_Entity
  • Syspay_Merchant_Entity_AstroPayBank
  • Syspay_Merchant_Entity_BillingAgreement
  • Syspay_Merchant_Entity_Chargeback
  • Syspay_Merchant_Entity_Creditcard
  • Syspay_Merchant_Entity_Customer
  • Syspay_Merchant_Entity_Eterminal
  • Syspay_Merchant_Entity_Payment
  • Syspay_Merchant_Entity_PaymentMethod
  • Syspay_Merchant_Entity_PaymentRecipient
  • Syspay_Merchant_Entity_Plan
  • Syspay_Merchant_Entity_Refund
  • Syspay_Merchant_Entity_Subscription
  • Syspay_Merchant_Entity_SubscriptionEvent
  • Syspay_Merchant_EterminalRequest
  • Syspay_Merchant_IpAddressesRequest
  • Syspay_Merchant_PaymentInfoRequest
  • Syspay_Merchant_PaymentListRequest
  • Syspay_Merchant_PaymentRequest
  • Syspay_Merchant_PlanInfoRequest
  • Syspay_Merchant_PlanRequest
  • Syspay_Merchant_PlanUpdateRequest
  • Syspay_Merchant_RebillRequest
  • Syspay_Merchant_Redirect
  • Syspay_Merchant_RefundInfoRequest
  • Syspay_Merchant_RefundListRequest
  • Syspay_Merchant_RefundRequest
  • Syspay_Merchant_Request
  • Syspay_Merchant_SubscriptionCancellationRequest
  • Syspay_Merchant_SubscriptionInfoRequest
  • Syspay_Merchant_SubscriptionRebillRequest
  • Syspay_Merchant_SubscriptionRequest
  • Syspay_Merchant_Utils
  • Syspay_Merchant_VoidRequest

Interfaces

  • Syspay_Merchant_Entity_ReturnedEntityInterface

Exceptions

  • Syspay_Merchant_EMSException
  • Syspay_Merchant_RedirectException
  • Syspay_Merchant_RequestException
  • Syspay_Merchant_UnexpectedResponseException
  • Overview
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Handle EMS (Event Messaging System) callbacks
  5:  *
  6:  * @see https://app.syspay.com/bundles/emiuser/doc/merchant_ems.html
  7:  */
  8: class Syspay_Merchant_EMS
  9: {
 10:     protected $secrets = array();
 11:     protected $skipAuthCheck;
 12:     protected $headers = array();
 13:     protected $content;
 14: 
 15:     /**
 16:      * Build an EMS handler
 17:      * @param array   $secrets       An array where each key is your merchant login and the value is the related passphrase
 18:      * @param boolean $skipAuthCheck Skip the checksum validation
 19:      */
 20:     public function __construct(array $secrets, $skipAuthCheck = false)
 21:     {
 22:         $this->secrets       = $secrets;
 23:         $this->skipAuthCheck = $skipAuthCheck;
 24: 
 25:         $this->headers['content-type'] = isset($_SERVER['CONTENT_TYPE'])?
 26:                                             $_SERVER['CONTENT_TYPE']:'application/x-www-form-urlencoded';
 27:         $this->headers['x-merchant']   = isset($_SERVER['HTTP_X_MERCHANT'])?$_SERVER['HTTP_X_MERCHANT']:null;
 28:         $this->headers['x-checksum']   = isset($_SERVER['HTTP_X_CHECKSUM'])?$_SERVER['HTTP_X_CHECKSUM']:null;
 29:         $this->headers['x-event-id']   = isset($_SERVER['HTTP_X_EVENT_ID'])?$_SERVER['HTTP_X_EVENT_ID']:null;
 30:         $this->headers['x-event-date'] = isset($_SERVER['HTTP_X_EVENT_DATE'])?$_SERVER['HTTP_X_EVENT_DATE']:null;
 31: 
 32:         $this->content = file_get_contents('php://input');
 33:     }
 34: 
 35:     /**
 36:      * Return the entity linked to the EMS call received
 37:      * @return mixed One of the Syspay_Merchant_Entity classes depending on the event received
 38:      * @throws Syspay_Merchant_EMSException If something went wrong while parsing the request
 39:      */
 40:     public function getEvent()
 41:     {
 42:         if (!$this->skipAuthCheck) {
 43:             $this->checkChecksum();
 44:         }
 45: 
 46:         $content = $this->getContent();
 47: 
 48:         if (!isset($content->type)) {
 49:             throw new Syspay_Merchant_EMSException(
 50:                 'Unable to get event type',
 51:                 Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 52:             );
 53:         }
 54: 
 55:         if (!isset($content->data)) {
 56:             throw new Syspay_Merchant_EMSException(
 57:                 'Unable to get data from content',
 58:                 Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 59:             );
 60:         }
 61: 
 62:         switch ($content->type) {
 63:             case 'payment':
 64:                 if (!isset($content->data->payment)) {
 65:                     throw new Syspay_Merchant_EMSException(
 66:                         'Payment event received with no payment data',
 67:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 68:                     );
 69:                 }
 70: 
 71:                 return Syspay_Merchant_Entity_Payment::buildFromResponse($content->data->payment);
 72:                 break;
 73:             case 'refund':
 74:                 if (!isset($content->data->refund)) {
 75:                     throw new Syspay_Merchant_EMSException(
 76:                         'Refund event received with no refund data',
 77:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 78:                     );
 79:                 }
 80: 
 81:                 return Syspay_Merchant_Entity_Refund::buildFromResponse($content->data->refund);
 82:                 break;
 83:             case 'chargeback':
 84:                 if (!isset($content->data->chargeback)) {
 85:                     throw new Syspay_Merchant_EMSException(
 86:                         'Chargeback event received with no chargeback data',
 87:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 88:                     );
 89:                 }
 90: 
 91:                 return Syspay_Merchant_Entity_Chargeback::buildFromResponse($content->data->chargeback);
 92:                 break;
 93:             case 'billing_agreement':
 94:                 if (!isset($content->data->billing_agreement)) {
 95:                     throw new Syspay_Merchant_EMSException(
 96:                         'Billing agreement event received with no billing_agreement data',
 97:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
 98:                     );
 99:                 }
100: 
101:                 return Syspay_Merchant_Entity_BillingAgreement::buildFromResponse($content->data->billing_agreement);
102:                 break;
103:             case 'subscription':
104:                 if (!isset($content->data->subscription)) {
105:                     throw new Syspay_Merchant_EMSException(
106:                         'Subscription event received with no subscription data',
107:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
108:                     );
109:                 }
110: 
111:                 return Syspay_Merchant_Entity_Subscription::buildFromResponse($content->data->subscription);
112:             default:
113:                 throw new Syspay_Merchant_EMSException(
114:                     'Unknown type: ' . $content->type,
115:                     Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
116:                 );
117:         }
118:     }
119: 
120:     /**
121:      * Validate the header's checksum
122:      * @throws Syspay_Merchant_EMSException If the checksum didn't validate
123:      */
124:     private function checkChecksum()
125:     {
126:         if (empty($this->headers['x-merchant'])) {
127:             throw new Syspay_Merchant_EMSException(
128:                 'Missing x-merchant header',
129:                 Syspay_Merchant_EMSException::CODE_MISSING_HEADER
130:             );
131:         }
132: 
133:         if (empty($this->headers['x-checksum'])) {
134:             throw new Syspay_Merchant_EMSException(
135:                 'Missing x-checksum header',
136:                 Syspay_Merchant_EMSException::CODE_MISSING_HEADER
137:             );
138:         }
139: 
140:         if (!isset($this->secrets[$this->headers['x-merchant']])) {
141:             throw new Syspay_Merchant_EMSException(
142:                 'Unknown merchant: ' . $this->headers['x-merchant'],
143:                 Syspay_Merchant_EMSException::CODE_UNKNOWN_MERCHANT
144:             );
145:         }
146: 
147:         if (!Syspay_Merchant_Utils::checkChecksum(
148:             $this->content,
149:             $this->secrets[$this->headers['x-merchant']],
150:             $this->headers['x-checksum']
151:         )) {
152:             throw new Syspay_Merchant_EMSException(
153:                 'Invalid checksum',
154:                 Syspay_Merchant_EMSException::CODE_INVALID_CHECKSUM
155:             );
156:         }
157:     }
158: 
159:     /**
160:      * Get the request's content
161:      * @return stdClass
162:      * @throws Syspay_Merchant_EMSException If the request body could not be parsed
163:      */
164:     private function getContent()
165:     {
166:         switch ($this->headers['content-type']) {
167:             case 'application/json':
168:                 $content = json_decode($this->content);
169:                 if (false === $content) {
170:                     throw new Syspay_Merchant_EMSException(
171:                         'Unable to parse request body, invalid json',
172:                         Syspay_Merchant_EMSException::CODE_INVALID_CONTENT
173:                     );
174:                 }
175: 
176:                 return $content;
177:             case 'application/x-www-form-urlencoded':
178:             default:
179:                 return self::toObject($_POST);
180:         }
181:     }
182: 
183:     /**
184:      * Return the event unique ID
185:      * @return string
186:      */
187:     public function getEventId()
188:     {
189:         return $this->headers['x-event-id'];
190:     }
191: 
192:     /**
193:      * Return the event creation date
194:      * @return DateTime
195:      */
196:     public function getEventDate()
197:     {
198:         if (isset($this->headers['x-event-date'])) {
199:             $date = new DateTime();
200:             $date->setTimestamp($this->headers['x-event-date']);
201:             return $date;
202:         }
203: 
204:         return null;
205:     }
206: 
207: 
208:     /**
209:      * Convert an array or a scalar to a stdClass object
210:      * @param mixed $a The input value
211:      *
212:      * @return stdClass Its object representation
213:      */
214:     private static function toObject($a)
215:     {
216:         if (is_array($a)) {
217:             return (object) array_map(array('Syspay_Merchant_EMS', 'toObject'), $a);
218:         }
219: 
220:         return $a;
221:     }
222: }
223: 
Syspay Merchant SDK API documentation generated by ApiGen 2.8.0