1: <?php
2:
3: 4: 5: 6: 7:
8: class Syspay_Merchant_EMS
9: {
10: protected $secrets = array();
11: protected $skipAuthCheck;
12: protected = array();
13: protected $content;
14:
15: 16: 17: 18: 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: 37: 38: 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: 122: 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: 161: 162: 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: 185: 186:
187: public function getEventId()
188: {
189: return $this->headers['x-event-id'];
190: }
191:
192: 193: 194: 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: 210: 211: 212: 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: