riskified_magento - Version 1.0.5.4

Version Notes

* validations fix to support shopgate

Download this release

Release Info

Developer Riskified_Mage
Extension riskified_magento
Version 1.0.5.4
Comparing to
See all releases


Version 1.0.5.4

Files changed (75) hide show
  1. app/code/community/Riskified/Full/Helper/Data.php +61 -0
  2. app/code/community/Riskified/Full/Helper/Debug.php +58 -0
  3. app/code/community/Riskified/Full/Helper/Log.php +14 -0
  4. app/code/community/Riskified/Full/Helper/Order.php +500 -0
  5. app/code/community/Riskified/Full/Helper/Order/Invoice.php +31 -0
  6. app/code/community/Riskified/Full/Helper/Order/Status.php +44 -0
  7. app/code/community/Riskified/Full/Model/Authorizenet.php +47 -0
  8. app/code/community/Riskified/Full/Model/Cron.php +86 -0
  9. app/code/community/Riskified/Full/Model/Observer.php +340 -0
  10. app/code/community/Riskified/Full/Model/Resource/Retry.php +9 -0
  11. app/code/community/Riskified/Full/Model/Resource/Retry/Collection.php +9 -0
  12. app/code/community/Riskified/Full/Model/Retry.php +9 -0
  13. app/code/community/Riskified/Full/Model/System/Config/Source/CaptureCase.php +15 -0
  14. app/code/community/Riskified/Full/Model/System/Config/Source/Env.php +13 -0
  15. app/code/community/Riskified/Full/Test/Config/General.php +59 -0
  16. app/code/community/Riskified/Full/Test/Helper/General.php +25 -0
  17. app/code/community/Riskified/Full/Test/Helper/General/fixtures/extensionConfigEnabled.yaml +7 -0
  18. app/code/community/Riskified/Full/Test/Model/Environments.php +22 -0
  19. app/code/community/Riskified/Full/controllers/Adminhtml/FullController.php +22 -0
  20. app/code/community/Riskified/Full/controllers/ResponseController.php +50 -0
  21. app/code/community/Riskified/Full/etc/config.xml +293 -0
  22. app/code/community/Riskified/Full/etc/system.xml +112 -0
  23. app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-install-1.0.1.php +14 -0
  24. app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-install-1.0.2.1.php +14 -0
  25. app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-upgrade-1.0.4-1.0.5.0.php +39 -0
  26. app/design/adminhtml/default/default/layout/full.xml +8 -0
  27. app/design/adminhtml/default/default/template/full/jsinit.phtml +251 -0
  28. app/design/frontend/base/default/layout/full.xml +9 -0
  29. app/design/frontend/base/default/template/full/riskified.phtml +19 -0
  30. app/etc/modules/Riskified_Full.xml +9 -0
  31. lib/riskified_php_sdk/.gitignore +3 -0
  32. lib/riskified_php_sdk/README.md +46 -0
  33. lib/riskified_php_sdk/sample/callback.php +63 -0
  34. lib/riskified_php_sdk/sample/order_webhook.php +215 -0
  35. lib/riskified_php_sdk/sample/run_callback_server.sh +20 -0
  36. lib/riskified_php_sdk/sample/upload_historical.php +83 -0
  37. lib/riskified_php_sdk/src/Riskified/Common/Env.php +31 -0
  38. lib/riskified_php_sdk/src/Riskified/Common/Exception/BaseException.php +17 -0
  39. lib/riskified_php_sdk/src/Riskified/Common/Riskified.php +82 -0
  40. lib/riskified_php_sdk/src/Riskified/Common/Signature/HttpDataSignature.php +40 -0
  41. lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/AuthorizationException.php +38 -0
  42. lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/BadHeaderException.php +35 -0
  43. lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/BadPostJsonException.php +22 -0
  44. lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/NotificationException.php +45 -0
  45. lib/riskified_php_sdk/src/Riskified/DecisionNotification/Model/Notification.php +87 -0
  46. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/ClassMismatchPropertyException.php +22 -0
  47. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/CurlException.php +24 -0
  48. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/FormatMismatchPropertyException.php +22 -0
  49. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/InvalidPropertyException.php +22 -0
  50. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MalformedJsonException.php +41 -0
  51. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MissingPropertyException.php +22 -0
  52. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MultiplePropertiesException.php +42 -0
  53. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/PropertyException.php +73 -0
  54. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/TypeMismatchPropertyException.php +22 -0
  55. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/UnsuccessfulActionException.php +45 -0
  56. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/AbstractModel.php +284 -0
  57. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Address.php +42 -0
  58. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Attribute.php +28 -0
  59. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/ClientDetails.php +31 -0
  60. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Customer.php +43 -0
  61. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/DiscountCode.php +28 -0
  62. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Fulfillment.php +39 -0
  63. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/LineItem.php +50 -0
  64. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Order.php +81 -0
  65. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/OrderCancellation.php +29 -0
  66. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/PaymentDetails.php +39 -0
  67. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Refund.php +28 -0
  68. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/RefundDetails.php +32 -0
  69. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/ShippingLine.php +32 -0
  70. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/TaxLine.php +29 -0
  71. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Transport/AbstractTransport.php +151 -0
  72. lib/riskified_php_sdk/src/Riskified/OrderWebhook/Transport/CurlTransport.php +81 -0
  73. lib/riskified_php_sdk/src/Riskified/autoloader.php +29 -0
  74. package.xml +20 -0
  75. skin/adminhtml/default/default/images/riskified/logo.jpg +0 -0
app/code/community/Riskified/Full/Helper/Data.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once(Mage::getBaseDir('lib') . DIRECTORY_SEPARATOR . 'riskified_php_sdk' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Riskified' . DIRECTORY_SEPARATOR . 'autoloader.php');
4
+
5
+ class Riskified_Full_Helper_Data extends Mage_Core_Helper_Abstract {
6
+
7
+ public function getAdminUrl(){
8
+ $out = null;
9
+ $match = preg_match("/(.*)full\/response\/getresponse.*/i", Mage::helper('adminhtml')->getUrl('full/response/getresponse'),$out);
10
+ if ($match){
11
+ return $out[1];
12
+ }else{
13
+ return "";
14
+ }
15
+ }
16
+
17
+ public function getAuthToken(){
18
+ return Mage::getStoreConfig('fullsection/full/key',Mage::app()->getStore());
19
+ }
20
+
21
+ public function getConfigStatusControlActive(){
22
+ return Mage::getStoreConfig('fullsection/full/order_status_sync');
23
+ }
24
+
25
+ public function getConfigEnv(){
26
+ return 'Riskified\Common\Env::' . Mage::getStoreConfig('fullsection/full/env');
27
+ }
28
+
29
+ public function getConfigBeaconUrl(){
30
+ return Mage::getStoreConfig('fullsection/full/beaconurl');
31
+ }
32
+
33
+ public function getShopDomain(){
34
+ return Mage::getStoreConfig('fullsection/full/domain');
35
+ }
36
+
37
+ public function getExtensionVersion(){
38
+ return (string) Mage::getConfig()->getNode()->modules->Riskified_Full->version;
39
+ }
40
+
41
+ public function getSessionId(){
42
+ $visitorData = Mage::getSingleton('core/session')->getVisitorData();
43
+ return $visitorData['session_id'];
44
+ }
45
+
46
+ /**
47
+ * @return string
48
+ */
49
+ public function getSdkVersion()
50
+ {
51
+ return Riskified\Common\Riskified::VERSION;
52
+ }
53
+
54
+ /**
55
+ * @return string
56
+ */
57
+ public function getSdkApiVersion()
58
+ {
59
+ return Riskified\Common\Riskified::API_VERSION;
60
+ }
61
+ }
app/code/community/Riskified/Full/Helper/Debug.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Helper_Debug extends Mage_Core_Helper_Abstract
4
+ {
5
+ const ALERT_EMAIL = 'assaf@riskified.com';
6
+ const CONFIG_SECTION = 'fullsection';
7
+
8
+ /**
9
+ * Send all relevant debug info to riskified
10
+ *
11
+ * @return void
12
+ */
13
+ public function sendDebugInfoToRiskified()
14
+ {
15
+ $debugData = $this->_getDebugData();
16
+
17
+ $mail = new Zend_Mail();
18
+ $mail->setBodyHtml(print_r($debugData, true))
19
+ ->setFrom(Mage::getStoreConfig('trans_email/ident_general/email'), Mage::getStoreConfig('trans_email/ident_general/name'))
20
+ ->addTo(self::ALERT_EMAIL)
21
+ ->setSubject('Magento Extension Debug Info for ' . Mage::getBaseUrl());
22
+
23
+ try {
24
+ $mail->send();
25
+ }
26
+ catch (Exception $e) {
27
+ Mage::helper('full/log')->logException($e);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @return array
33
+ */
34
+ protected function _getDebugData()
35
+ {
36
+ $helper = Mage::helper('full');
37
+
38
+ // Relevant version numbers
39
+ $data = array(
40
+ 'magentoVersion' => Mage::getVersion(),
41
+ 'magentoExtensionVersion' => $helper->getExtensionVersion(),
42
+ 'magentoBaseUrl' => Mage::getBaseUrl(),
43
+ 'sdkVersion' => $helper->getSdkVersion(),
44
+ 'sdkApiVersion' => $helper->getSdkApiVersion()
45
+ );
46
+
47
+ // All Riskified config values
48
+ $configGroups = Mage::getStoreConfig(self::CONFIG_SECTION);
49
+
50
+ foreach($configGroups as $groupName => $group) {
51
+ foreach($group as $fieldName => $field) {
52
+ $data['magentoConfig-' . self::CONFIG_SECTION . '/' . $groupName . '/' . $fieldName] = $field;
53
+ }
54
+ }
55
+
56
+ return $data;
57
+ }
58
+ }
app/code/community/Riskified/Full/Helper/Log.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Helper_Log extends Mage_Core_Helper_Abstract
4
+ {
5
+ public function log($message, $level = null)
6
+ {
7
+ Mage::log($message, $level, 'riskified_full.log');
8
+ }
9
+
10
+ public function logException($e)
11
+ {
12
+ $this->log("Riskified extension had an exception: " . $e->getMessage());
13
+ }
14
+ }
app/code/community/Riskified/Full/Helper/Order.php ADDED
@@ -0,0 +1,500 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once(Mage::getBaseDir('lib') . DIRECTORY_SEPARATOR . 'riskified_php_sdk' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Riskified' . DIRECTORY_SEPARATOR . 'autoloader.php');
4
+ use Riskified\Common\Riskified;
5
+ use Riskified\Common\Signature;
6
+ use Riskified\OrderWebhook\Model;
7
+ use Riskified\OrderWebhook\Transport;
8
+ use Riskified\DecisionNotification\Model\Notification as DecisionNotification;
9
+
10
+
11
+ class Riskified_Full_Helper_Order extends Mage_Core_Helper_Abstract {
12
+ const ACTION_CREATE = 'create';
13
+ const ACTION_UPDATE = 'update';
14
+ const ACTION_SUBMIT = 'submit';
15
+ const ACTION_CANCEL = 'cancel';
16
+
17
+ public function __construct() {
18
+ $this->initSdk();
19
+ }
20
+
21
+ /**
22
+ * Submit an order to Riskified.
23
+ *
24
+ * @param Mage_Sales_Model_Order $order
25
+ * @param string $action - one of self::ACTION_*
26
+ * @return stdClass
27
+ * @throws Exception
28
+ */
29
+ public function postOrder($order, $action) {
30
+ $transport = $this->getTransport();
31
+ $headers = $this->getHeaders();
32
+
33
+ Mage::helper('full/log')->log('postOrder ' . serialize($headers) . ' - ' . $action);
34
+
35
+ $eventData = array(
36
+ 'order' => $order,
37
+ 'action' => $action
38
+ );
39
+
40
+ try {
41
+ switch ($action) {
42
+ case self::ACTION_CREATE:
43
+ $orderForTransport = $this->getOrder($order);
44
+ $response = $transport->createOrder($orderForTransport);
45
+
46
+ break;
47
+ case self::ACTION_UPDATE:
48
+ $orderForTransport = $this->getOrder($order);
49
+ $response = $transport->updateOrder($orderForTransport);
50
+
51
+ break;
52
+ case self::ACTION_SUBMIT:
53
+ $orderForTransport = $this->getOrder($order);
54
+ $response = $transport->submitOrder($orderForTransport);
55
+
56
+ break;
57
+ case self::ACTION_CANCEL:
58
+ $orderForTransport = $this->getOrderCancellation($order);
59
+ $response = $transport->cancelOrder($orderForTransport);
60
+
61
+ break;
62
+ }
63
+
64
+ $eventData['response'] = $response;
65
+
66
+ Mage::dispatchEvent(
67
+ 'riskified_full_post_order_success',
68
+ $eventData
69
+ );
70
+ } catch(\Riskified\OrderWebhook\Exception\CurlException $curlException) {
71
+ Mage::helper('full/log')->logException($curlException);
72
+ Mage::getSingleton('adminhtml/session')->addError('Riskified extension: ' . $curlException->getMessage());
73
+
74
+ $this->updateOrder($order, 'error', 'Error transferring order data to Riskified');
75
+ $this->scheduleSubmissionRetry($order, $action);
76
+
77
+ Mage::dispatchEvent(
78
+ 'riskified_full_post_order_error',
79
+ $eventData
80
+ );
81
+
82
+ throw $curlException;
83
+ }
84
+ catch (Exception $e) {
85
+ Mage::helper('full/log')->logException($e);
86
+ Mage::getSingleton('adminhtml/session')->addError('Riskified extension: ' . $e->getMessage());
87
+
88
+ Mage::dispatchEvent(
89
+ 'riskified_full_post_order_error',
90
+ $eventData
91
+ );
92
+
93
+ throw $e;
94
+ }
95
+
96
+ return $response;
97
+ }
98
+
99
+ public function postHistoricalOrders($models) {
100
+ $orders = array();
101
+ foreach ($models as $model) {
102
+ $orders[] = $this->getOrder($model);
103
+ }
104
+
105
+ $msgs = $this->getTransport()->sendHistoricalOrders($orders);
106
+ return "Successfully uploaded ".count($msgs)." orders.".PHP_EOL;
107
+ }
108
+
109
+ /**
110
+ * Dispatch events for order update handling
111
+ *
112
+ * Possible events are:
113
+ * - riskified_order_update
114
+ * - riskified_order_update_approved
115
+ * - riskified_order_update_declined
116
+ * - riskified_order_update_submitted
117
+ * - riskified_order_update_captured
118
+ * - riskified_order_update_error
119
+ * - riskified_order_update_?
120
+ *
121
+ * @param Mage_Sales_Model_Order $order
122
+ * @param string $status
123
+ * @param string $description
124
+ * @return void
125
+ */
126
+ public function updateOrder($order, $status, $description) {
127
+ Mage::helper('full/log')->log('Dispatching event for order ' . $order->getId() . ' with status "' . $status . '" and description "' . $description . '"');
128
+
129
+ $eventData = array(
130
+ 'order' => $order,
131
+ 'status' => $status,
132
+ 'description' => $description
133
+ );
134
+
135
+ // A generic event for all updates
136
+ Mage::dispatchEvent(
137
+ 'riskified_full_order_update',
138
+ $eventData
139
+ );
140
+
141
+ // A status-specific event
142
+ $eventIdentifier = preg_replace("/[^a-z]/", '_', strtolower($status));
143
+
144
+ Mage::dispatchEvent(
145
+ 'riskified_full_order_update_' . $eventIdentifier,
146
+ $eventData
147
+ );
148
+
149
+ return;
150
+ }
151
+
152
+ public function getRiskifiedDomain() {
153
+ return Riskified::getHostByEnv();
154
+ }
155
+
156
+ public function parseRequest($request) {
157
+ $header_name = Signature\HttpDataSignature::HMAC_HEADER_NAME;
158
+ $headers = array($header_name => $request->getHeader($header_name));
159
+ $body = $request->getRawBody();
160
+ Mage::helper('full/log')->log("Received new notification request with headers: " . json_encode($headers) . " and body: $body. Trying to parse.");
161
+ return new
162
+ DecisionNotification(new Signature\HttpDataSignature(), $headers, $body);
163
+ }
164
+
165
+ private $version;
166
+
167
+ private function initSdk() {
168
+ $helper = Mage::helper('full');
169
+ $authToken = $helper->getAuthToken();
170
+ $env = constant($helper->getConfigEnv());
171
+ $shopDomain = $helper->getShopDomain();
172
+ $this->version = $helper->getExtensionVersion();
173
+ $sdkVersion = Riskified::VERSION;
174
+
175
+ Mage::helper('full/log')->log("Riskified initSdk() - shop: $shopDomain, env: $env, token: $authToken, extension_version: $this->version, sdk_version: $sdkVersion");
176
+ Riskified::init($shopDomain, $authToken, $env, \Riskified\Common\Validations::SKIP);
177
+ }
178
+
179
+ private function getHeaders() {
180
+ return array('headers' => array('X_RISKIFIED_VERSION:'.$this->version));
181
+ }
182
+
183
+ private function getTransport() {
184
+ $transport = new Transport\CurlTransport(new Signature\HttpDataSignature());
185
+ $transport->timeout = 15;
186
+ return $transport;
187
+ }
188
+
189
+ private function getOrderCancellation($model) {
190
+ $orderCancellation = new Model\OrderCancellation(array_filter(array(
191
+ 'id' => $model->getId(),
192
+ 'cancelled_at' => $this->formatDateAsIso8601($this->getCancelledAt($model)),
193
+ 'cancel_reason' => 'Cancelled by merchant'
194
+ )));
195
+
196
+ Mage::helper('full/log')->log("getOrderCancellation(): ".PHP_EOL.json_encode(json_decode($orderCancellation->toJson())));
197
+
198
+ return $orderCancellation;
199
+ }
200
+
201
+ private function getOrder($model) {
202
+ $order = new Model\Order(array_filter(array(
203
+ 'id' => $model->getId(),
204
+ 'name' => $model->getIncrementId(),
205
+ 'email' => $model->getCustomerEmail(),
206
+ 'created_at' => $this->formatDateAsIso8601($model->getCreatedAt()),
207
+ 'currency' => $model->getOrderCurrencyCode(), // was getBaseCurrencyCode() before by mistake
208
+ 'updated_at' => $this->formatDateAsIso8601($model->getUpdatedAt()),
209
+ 'gateway' => $model->getPayment()->getMethod(),
210
+ 'browser_ip' => $this->getRemoteIp($model),
211
+ 'cart_token' => Mage::helper('full')->getSessionId(),
212
+ 'note' => $model->getCustomerNote(),
213
+ 'total_price' => $model->getGrandTotal(),
214
+ 'total_discounts' => $model->getDiscountAmount(),
215
+ 'subtotal_price' => $model->getBaseSubtotalInclTax(),
216
+ 'discount_codes' =>$this->getDiscountCodes($model),
217
+ 'taxes_included' => true,
218
+ 'total_tax' => $model->getBaseTaxAmount(),
219
+ 'total_weight' => $model->getWeight(),
220
+ 'cancelled_at' => $this->formatDateAsIso8601($this->getCancelledAt($model)),
221
+ 'financial_status' => $model->getState()
222
+ ),'strlen'));
223
+
224
+ $order->customer = $this->getCustomer($model);
225
+ $order->shipping_address = $this->getShippingAddress($model);
226
+ $order->billing_address = $this->getBillingAddress($model);
227
+ $order->payment_details = $this->getPaymentDetails($model);
228
+ $order->line_items = $this->getLineItems($model);
229
+ $order->shipping_lines = $this->getShippingLines($model);
230
+ $order->client_details = $this->getClientDetails($model);
231
+
232
+ Mage::helper('full/log')->log("getOrder(): ".PHP_EOL.json_encode(json_decode($order->toJson())));
233
+
234
+ return $order;
235
+ }
236
+
237
+ private function getCustomer($model) {
238
+ $customer_id = $model->getCustomerId();
239
+ $customer_props = array(
240
+ 'id' => $customer_id,
241
+ 'email' => $model->getCustomerEmail(),
242
+ 'first_name' => $model->getCustomerFirstname(),
243
+ 'last_name' => $model->getCustomerLastname(),
244
+ 'note' => $model->getCustomerNote(),
245
+ );
246
+
247
+ if ($customer_id) {
248
+ $customer_details = Mage::getModel('customer/customer')->load($customer_id);
249
+ $customer_props['created_at'] = $this->formatDateAsIso8601($customer_details->getCreatedAt());
250
+ $customer_props['updated_at'] = $this->formatDateAsIso8601($customer_details->getUpdatedAt());
251
+
252
+ $customer_orders = Mage::getModel('sales/order')->getCollection()->addFieldToFilter('customer_id', $customer_id);
253
+ $customer_orders_count = $customer_orders->count();
254
+
255
+ $customer_props['orders_count'] = $customer_orders_count;
256
+ if ($customer_orders_count) {
257
+ $customer_props['last_order_id'] = $customer_orders->getLastItem()->getId();
258
+ $customer_props['total_spent'] = array_sum($customer_orders->getColumnValues('base_grand_total'));
259
+ }
260
+ }
261
+
262
+ return new Model\Customer(array_filter($customer_props,'strlen'));
263
+ }
264
+
265
+ private function getShippingAddress($model) {
266
+ $mageAddr = $model->getShippingAddress();
267
+ return $this->getAddress($mageAddr);
268
+ }
269
+
270
+ private function getBillingAddress($model) {
271
+ $mageAddr = $model->getBillingAddress();
272
+ return $this->getAddress($mageAddr);
273
+ }
274
+
275
+ private function getPaymentDetails($model) {
276
+ $payment = $model->getPayment();
277
+ if(!$payment) {
278
+ return null;
279
+ }
280
+
281
+ $transactionId = $payment->getTransactionId();
282
+
283
+ $gateway_name = $payment->getMethod();
284
+ switch ($gateway_name) {
285
+ case 'authorizenet':
286
+ $cards_data = array_values($payment->getAdditionalInformation('authorize_cards'));
287
+ $card_data = $cards_data[0];
288
+ $avs_result_code = $card_data['cc_avs_result_code']; // getAvsResultCode
289
+ $cvv_result_code = $card_data['cc_response_code']; // getCardCodeResponseCode
290
+ $credit_card_number = $card_data['cc_last4'];
291
+ $credit_card_company = $card_data['cc_type'];
292
+ break;
293
+ case 'paypal_express':
294
+ case 'paypaluk_express':
295
+ $payer_email = $payment->getAdditionalInformation('paypal_payer_email');
296
+ $payer_status = $payment->getAdditionalInformation('paypal_payer_status');
297
+ $payer_address_status = $payment->getAdditionalInformation('paypal_address_status');
298
+ $protection_eligibility = $payment->getAdditionalInformation('paypal_protection_eligibility');
299
+ $payment_status = $payment->getAdditionalInformation('paypal_payment_status');
300
+ $pending_reason = $payment->getAdditionalInformation('paypal_pending_reason');
301
+
302
+ return new Model\PaymentDetails(array_filter(array(
303
+ 'authorization_id' => $transactionId,
304
+ 'payer_email' => $payer_email,
305
+ 'payer_status' => $payer_status,
306
+ 'payer_address_status' => $payer_address_status,
307
+ 'protection_eligibility' => $protection_eligibility,
308
+ 'payment_status' => $payment_status,
309
+ 'pending_reason' => $pending_reason
310
+ ),'strlen'));
311
+
312
+ case 'paypal_direct':
313
+ case 'paypaluk_direct':
314
+ $avs_result_code = $payment->getAdditionalInformation('paypal_avs_code');
315
+ $cvv_result_code = $payment->getAdditionalInformation('paypal_cvv2_match');
316
+ $credit_card_number = $payment->getCcLast4();
317
+ $credit_card_company = $payment->getCcType();
318
+ break;
319
+
320
+ case 'sagepaydirectpro':
321
+ $sage = $model->getSagepayInfo();
322
+ $avs_result_code = $sage->getData('address_result');
323
+ $cvv_result_code = $sage->getData('cv2result');
324
+ $credit_card_number = $sage->getData('last_four_digits');
325
+ $credit_card_company = $sage->getData('card_type');
326
+ break;
327
+
328
+ default:
329
+ Mage::helper('full/log')->log("unknown gateway:". $gateway_name);
330
+ break;
331
+ }
332
+
333
+ if (!$cvv_result_code) {
334
+ $cvv_result_code = $payment->getCcCidStatus();
335
+ }
336
+ if (!$credit_card_number) {
337
+ $credit_card_number = $payment->getCcLast4();
338
+ }
339
+ if (!$credit_card_company) {
340
+ $credit_card_company = $payment->getCcType();
341
+ }
342
+ if (!$avs_result_code) {
343
+ $avs_result_code = $payment->getCcAvsStatus();
344
+ }
345
+
346
+ if($credit_card_number) {
347
+ $credit_card_number = "XXXX-XXXX-XXXX-" . $credit_card_number;
348
+ }
349
+ $credit_card_bin = $payment->getAdditionalInformation('riskified_cc_bin');
350
+
351
+ return new Model\PaymentDetails(array_filter(array(
352
+ 'authorization_id' => $transactionId,
353
+ 'avs_result_code' => $avs_result_code,
354
+ 'cvv_result_code' => $cvv_result_code,
355
+ 'credit_card_number' => $credit_card_number,
356
+ 'credit_card_company' => $credit_card_company,
357
+ 'credit_card_bin' => $credit_card_bin
358
+ ),'strlen'));
359
+ }
360
+
361
+ private function getLineItems($model) {
362
+ $line_items = array();
363
+ //foreach ($model->getItemsCollection() as $key => $val) {
364
+ foreach ($model->getAllVisibleItems() as $key => $val) {
365
+ $line_items[] = new Model\LineItem(array_filter(array(
366
+ 'price' => $val->getPrice(),
367
+ 'quantity' => intval($val->getQtyOrdered()),
368
+ 'title' => $val->getName(),
369
+ 'sku' => $val->getSku(),
370
+ 'product_id' => $val->getItemId(),
371
+ 'grams' => $val->getWeight(),
372
+ 'vendor' => $model->getStoreName()
373
+ ),'strlen'));
374
+ }
375
+ return $line_items;
376
+ }
377
+
378
+ private function getShippingLines($model) {
379
+ return new Model\ShippingLine(array_filter(array(
380
+ 'price' => $model->getShippingAmount(),
381
+ 'title' => $model->getShippingDescription(),
382
+ 'code' => $model->getShippingMethod()
383
+ ),'strlen'));
384
+ }
385
+
386
+ private function getClientDetails($model) {
387
+ return new Model\ClientDetails(array_filter(array(
388
+ 'accept_language' => Mage::app()->getLocale()->getLocaleCode(),
389
+ 'browser_ip' => $this->getRemoteIp($model),
390
+ 'user_agent' => Mage::helper('core/http')->getHttpUserAgent()
391
+ ),'strlen'));
392
+ }
393
+
394
+ private function getAddress($address) {
395
+ if(!$address) {
396
+ return null;
397
+ }
398
+
399
+ $street = $address->getStreet();
400
+ $address_1 = (!is_null($street) && array_key_exists('0', $street)) ? $street['0'] : null;
401
+ $address_2 = (!is_null($street) && array_key_exists('1', $street)) ? $street['1'] : null;
402
+
403
+ $addrArray = array_filter(array(
404
+ 'first_name' => $address->getFirstname(),
405
+ 'last_name' => $address->getLastname(),
406
+ 'name' => $address->getFirstname() . " " . $address->getLastname(),
407
+ 'company' => $address->getCompany(),
408
+ 'address1' => $address_1,
409
+ 'address2' => $address_2,
410
+ 'city' => $address->getCity(),
411
+ 'country_code' => $address->getCountryId(),
412
+ 'country' => Mage::getModel('directory/country')->load($address->getCountryId())->getName(),
413
+ 'province' => $address->getRegion(),
414
+ 'zip' => $address->getPostcode(),
415
+ 'phone' => $address->getTelephone(),
416
+ ), 'strlen');
417
+
418
+ if(!$addrArray) {
419
+ return null;
420
+ }
421
+ return new Model\Address($addrArray);
422
+ }
423
+
424
+ private function getDiscountCodes($model) {
425
+ $code = $model->getDiscountDescription();
426
+ $amount = $model->getDiscountAmount();
427
+ if ($amount && $code)
428
+ return new Model\DiscountCode(array_filter(array(
429
+ 'code' => $code,
430
+ 'amount' => $amount
431
+ )));
432
+ return null;
433
+ }
434
+
435
+ private function getCancelledAt($model) {
436
+ $commentCollection = $model->getStatusHistoryCollection();
437
+ foreach ($commentCollection as $comment) {
438
+ if ($comment->getStatus() == Mage_Sales_Model_Order::STATE_CANCELED) {
439
+ return 'now';
440
+ }
441
+ }
442
+ return null;
443
+ }
444
+
445
+ private function formatDateAsIso8601($dateStr) {
446
+ return ($dateStr==NULL) ? NULL : date('c',strtotime($dateStr));
447
+ }
448
+
449
+ private function getRemoteIp($model) {
450
+ Mage::helper('full/log')->log("remote ip: " . $model->getRemoteIp() . ", x-forwarded-ip: " . $model->getXForwardedFor());
451
+
452
+ $forwardedIp = $model->getXForwardedFor();
453
+ $forwardeds = preg_split("/,/",$forwardedIp, -1, PREG_SPLIT_NO_EMPTY);
454
+ if (!empty($forwardeds)) {
455
+ return trim($forwardeds[0]);
456
+ }
457
+ $remoteIp = $model->getRemoteIp();
458
+ $remotes = preg_split("/,/",$remoteIp, -1, PREG_SPLIT_NO_EMPTY);
459
+ if (!empty($remotes)) {
460
+ return trim($remotes[0]);
461
+ }
462
+
463
+ return $remoteIp;
464
+ }
465
+
466
+ /**
467
+ * Schedule an attempt to retry this order submission. This should be called any time a submission attempt fails.
468
+ *
469
+ * @param Mage_Sales_Model_Order $order
470
+ * @param string $action - one of self::ACTION_*
471
+ * @return void
472
+ */
473
+ public function scheduleSubmissionRetry(Mage_Sales_Model_Order $order, $action)
474
+ {
475
+ Mage::helper('full/log')->log("Scheduling submission retry for order " . $order->getId());
476
+
477
+ try {
478
+ $existingRetries = Mage::getModel('full/retry')->getCollection()
479
+ ->addfieldtofilter('order_id', $order->getId())
480
+ ->addfieldtofilter('action', $action);
481
+
482
+ // Only schedule a retry if one doesn't exist for this order/action combination.
483
+ // If one already exists it will be updated in Riskified_Full_Model_Cron::retrySubmissions() so
484
+ // there is no need to do anything here (eg update the existing retry).
485
+ if ($existingRetries->count() == 0) {
486
+ Mage::getModel('full/retry')
487
+ ->addData(array(
488
+ 'order_id' => $order->getId(),
489
+ 'action' => $action,
490
+ 'updated_at' => Mage::getSingleton('core/date')->gmtDate()
491
+ ))
492
+ ->save();
493
+
494
+ Mage::helper('full/log')->log("New retry scheduled successfully");
495
+ }
496
+ } catch (Exception $e) {
497
+ Mage::helper('full/log')->logException($e);
498
+ }
499
+ }
500
+ }
app/code/community/Riskified/Full/Helper/Order/Invoice.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Helper_Order_Invoice extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
+ /**
7
+ * Has this user enabled auto-invoicing when orders are approved?
8
+ *
9
+ * @return bool
10
+ */
11
+ public function isAutoInvoiceEnabled()
12
+ {
13
+ return (bool) Mage::getStoreConfig('fullsection/full/auto_invoice_enabled');
14
+ }
15
+
16
+ /**
17
+ * Get the capture case to be used during auto-invoicing
18
+ *
19
+ * @return string
20
+ */
21
+ public function getCaptureCase()
22
+ {
23
+ $case = Mage::getStoreConfig('fullsection/full/auto_invoice_capture_case');
24
+
25
+ if (!in_array($case, array(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE, Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE))) {
26
+ $case = Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE;
27
+ }
28
+
29
+ return $case;
30
+ }
31
+ }
app/code/community/Riskified/Full/Helper/Order/Status.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Helper_Order_Status extends Mage_Core_Helper_Abstract
4
+ {
5
+ /**
6
+ * Get Riskified's custom "on hold for review" status code
7
+ *
8
+ * @return string
9
+ */
10
+ public function getOnHoldStatusCode()
11
+ {
12
+ return 'riskified_holded';
13
+ }
14
+
15
+ /**
16
+ * Get Riskified's custom "on hold for review" status label
17
+ *
18
+ * @return string
19
+ */
20
+ public function getOnHoldStatusLabel()
21
+ {
22
+ return 'On Hold (Riskified)';
23
+ }
24
+
25
+ /**
26
+ * Get Riskified's custom "on hold due to transport error" status code
27
+ *
28
+ * @return string
29
+ */
30
+ public function getTransportErrorStatusCode()
31
+ {
32
+ return 'riskified_trans_error';
33
+ }
34
+
35
+ /**
36
+ * Get Riskified's custom "on hold due to transport error" status label
37
+ *
38
+ * @return string
39
+ */
40
+ public function getTransportErrorStatusLabel()
41
+ {
42
+ return 'On Hold (Riskified Transport Error)';
43
+ }
44
+ }
app/code/community/Riskified/Full/Model/Authorizenet.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Paygate
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+
28
+ class Riskified_Full_Model_Authorizenet extends Mage_Paygate_Model_Authorizenet
29
+ {
30
+ /**
31
+ * it sets card`s data into additional information of payment model
32
+ *
33
+ * @param mage_paygate_model_authorizenet_result $response
34
+ * @param mage_sales_model_order_payment $payment
35
+ * @return varien_object
36
+ */
37
+ protected function _registercard(varien_object $response, mage_sales_model_order_payment $payment)
38
+ {
39
+ Mage::helper('full/log')->log( "in inherited _registercard." );
40
+ $card=parent::_registercard($response,$payment);
41
+ $card->setCcAvsResultCode($response->getAvsResultCode());
42
+ $card->setCcResponseCode($response->getCardCodeResponseCode());
43
+ $payment->setCcAvsStatus($response->getAvsResultCode());
44
+ $payment->setCcCidStatus($response->getCardCodeResponseCode());
45
+ return $card;
46
+ }
47
+ }
app/code/community/Riskified/Full/Model/Cron.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_Cron
4
+ {
5
+ /**
6
+ * Maximum number of times we'll attempt to resubmit an order
7
+ */
8
+ const MAX_ATTEMPTS = 7;
9
+
10
+ /**
11
+ * The base for calculating the exponential backoff
12
+ */
13
+ const INTERVAL_BASE = 3;
14
+
15
+ /**
16
+ * The maximum number of orders to try per cron run
17
+ */
18
+ const BATCH_SIZE = 10;
19
+
20
+ /**
21
+ * Attempt to retry order submissions
22
+ */
23
+ public function retrySubmissions()
24
+ {
25
+ Mage::helper('full/log')->log("Retrying failed order submissions");
26
+
27
+ // Load all retries that haven't reached the max number of attempts and are past due to run.
28
+ // Past due is calculated as self::INTERVAL_BASE ^ attempts. This results in an exponential backoff
29
+ // if this submission continues to fail.
30
+ $retries = Mage::getModel('full/retry')->getCollection()
31
+ //->addExpressionFieldToSelect(
32
+ // 'minutes_late',
33
+ // "TIMESTAMPDIFF(MINUTE, `updated_at`, '" . Mage::getSingleton('core/date')->gmtDate() . "') - POW(" . self::INTERVAL_BASE . ", attempts)",
34
+ // array()
35
+ //)
36
+ ->addfieldtofilter('attempts',
37
+ array(
38
+ array('lt' => self::MAX_ATTEMPTS)
39
+ )
40
+ );
41
+
42
+ $select = $retries->getSelect();
43
+ $adapter = $select->getAdapter();
44
+ $select
45
+ ->where(sprintf(
46
+ "TIMESTAMPDIFF(MINUTE, `updated_at`, %s) - POW(%s, attempts) > 0"
47
+ , $adapter->quote(Mage::getSingleton('core/date')->gmtDate())
48
+ , $adapter->quote(self::INTERVAL_BASE)
49
+ ))
50
+ ->order('updated_at ASC')
51
+ ->limit(self::BATCH_SIZE)
52
+ ;
53
+
54
+ foreach($retries as $retry) {
55
+ Mage::helper('full/log')->log("Retrying order " . $retry->getOrderId());
56
+
57
+ $order = Mage::getModel('sales/order')->load($retry->getOrderId());
58
+
59
+ if (!$order) {
60
+ Mage::helper('full/log')->log("Order doesn't exist, skipping");
61
+
62
+ $retry->delete();
63
+ continue;
64
+ }
65
+
66
+ try {
67
+ Mage::helper('full/order')->postOrder($order, $retry->getAction());
68
+
69
+ // There is no need to delete the retry here. postOrder() dispatches a success event which
70
+ // results in all retries for this order getting deleted.
71
+ }
72
+ // Log the exception, store the backtrace and increment the counter
73
+ catch (Exception $e) {
74
+ Mage::helper('full/log')->logException($e);
75
+
76
+ $retry
77
+ ->setLastError("Exception Message: " . $e->getMessage() . "\n\n" . Varien_Debug::backtrace(true, false))
78
+ ->setAttempts($retry->getAttempts() + 1)
79
+ ->setUpdatedAt(Mage::getSingleton('core/date')->gmtDate())
80
+ ->save();
81
+ }
82
+ }
83
+
84
+ Mage::helper('full/log')->log("Done retrying failed order submissions");
85
+ }
86
+ }
app/code/community/Riskified/Full/Model/Observer.php ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_Observer {
4
+
5
+ public function saveOrderBefore($evt) {
6
+ Mage::helper('full/log')->log("saveOrderBefore");
7
+
8
+ $payment = $evt->getPayment();
9
+ $cc_bin = substr($payment->getCcNumber(),0,6);
10
+
11
+ if ($cc_bin) {
12
+ $payment->setAdditionalInformation('riskified_cc_bin', $cc_bin);
13
+ }
14
+ }
15
+
16
+ public function salesOrderPaymentPlaceEnd($evt) {
17
+ Mage::helper('full/log')->log("salesOrderPaymentPlaceEnd");
18
+
19
+ //$order = $evt->getPayment()->getOrder();
20
+
21
+ //try {
22
+ // Mage::helper('full/order')->postOrder($order, Riskified_Full_Helper_Order::ACTION_CREATE);
23
+ //} catch (Exception $e) {
24
+ // There is no need to do anything here. The exception has already been handled and a retry scheduled.
25
+ // We catch this exception so that the order is still saved in Magento.
26
+ //}
27
+ }
28
+
29
+ public function salesOrderPaymentVoid($evt) {
30
+ Mage::helper('full/log')->log("salesOrderPaymentVoid");
31
+ //$order = $evt->getPayment()->getOrder();
32
+ //Mage::helper('full/order')->postOrder($order,'cancel');
33
+ }
34
+
35
+ public function salesOrderPaymentRefund($evt) {
36
+ Mage::helper('full/log')->log("salesOrderPaymentRefund");
37
+ //$order = $evt->getPayment()->getOrder();
38
+ //Mage::helper('full/order')->postOrder($order,'cancel');
39
+ }
40
+
41
+ public function salesOrderPaymentCancel($evt) {
42
+ Mage::helper('full/log')->log("salesOrderPaymentCancel");
43
+ //$order = $evt->getPayment()->getOrder();
44
+ //Mage::helper('full/order')->postOrder($order,'cancel');
45
+ }
46
+
47
+ public function salesOrderPlaceBefore($evt) {
48
+ Mage::helper('full/log')->log("salesOrderPlaceBefore");
49
+ }
50
+
51
+ public function salesOrderPlaceAfter($evt) {
52
+ Mage::helper('full/log')->log("salesOrderPlaceAfter");
53
+ }
54
+
55
+ public function salesOrderSaveBefore($evt) {
56
+ Mage::helper('full/log')->log("salesOrderSaveBefore");
57
+ }
58
+
59
+ public function salesOrderSaveAfter($evt) {
60
+ Mage::helper('full/log')->log("salesOrderSaveAfter");
61
+
62
+ $order = $evt->getOrder();
63
+ if(!$order) {
64
+ return;
65
+ }
66
+
67
+ $newState = $order->getState();
68
+
69
+ if ($order->dataHasChangedFor('state')) {
70
+ Mage::helper('full/log')->log("Order: " . $order->getId() . " state changed from: " . $order->getOrigData('state') . " to: " . $newState);
71
+
72
+ // if we posted we should not re post
73
+ if($order->riskifiedInSave) {
74
+ Mage::helper('full/log')->log("Order : " . $order->getId() . " is already riskifiedInSave");
75
+ return;
76
+ }
77
+ // Flag order to indicate that we are posting
78
+ $order->riskifiedInSave = true;
79
+
80
+ try {
81
+ Mage::helper('full/order')->postOrder($order, Riskified_Full_Helper_Order::ACTION_UPDATE);
82
+ } catch (Exception $e) {
83
+ // There is no need to do anything here. The exception has already been handled and a retry scheduled.
84
+ // We catch this exception so that the order is still saved in Magento.
85
+ }
86
+ } else {
87
+ Mage::helper('full/log')->log("Order: '" . $order->getId() . "' state didn't change on save - not posting again: " . $newState);
88
+ }
89
+ }
90
+
91
+ public function salesOrderCancel($evt) {
92
+ Mage::helper('full/log')->log("salesOrderCancel");
93
+
94
+ $order = $evt->getOrder();
95
+
96
+ // TODO not sure if this is still required - saveAfter should be enough
97
+
98
+ try {
99
+ Mage::helper('full/order')->postOrder($order, Riskified_Full_Helper_Order::ACTION_CANCEL);
100
+ } catch (Exception $e) {
101
+ // There is no need to do anything here. The exception has already been handled and a retry scheduled.
102
+ // We catch this exception so that the order is still saved in Magento.
103
+ }
104
+ }
105
+
106
+ public function postOrderIds($order_ids) {
107
+ foreach ($order_ids as $order_id) {
108
+ $order = Mage::getModel('sales/order')->load($order_id);
109
+
110
+ try {
111
+ Mage::helper('full/order')->postOrder($order, Riskified_Full_Helper_Order::ACTION_SUBMIT);
112
+ } catch (Exception $e) {
113
+ // There is no need to do anything here. The exception has already been handled and a retry scheduled.
114
+ // We catch this exception so that the order is still saved in Magento.
115
+ }
116
+ }
117
+ }
118
+
119
+ public function addMassAction($observer) {
120
+ $block = $observer->getEvent()->getBlock();
121
+ if(get_class($block) =='Mage_Adminhtml_Block_Widget_Grid_Massaction'
122
+ && $block->getRequest()->getControllerName() == 'sales_order')
123
+ {
124
+ $block->addItem('full', array(
125
+ 'label' => 'Submit to Riskified',
126
+ 'url' => Mage::app()->getStore()->getUrl('full/adminhtml_full/riskimass'),
127
+ ));
128
+ }
129
+ }
130
+
131
+ public function blockHtmlBefore($observer) {
132
+ $block = $observer->getEvent()->getBlock();
133
+ if ($block->getType() == 'adminhtml/sales_order_view') {
134
+ $message = Mage::helper('sales')->__('Are you sure you want to submit this order to Riskified?');
135
+ $url = $block->getUrl('full/adminhtml_full/riski');
136
+ $block->addButton('riski_submit', array(
137
+ 'label' => Mage::helper('sales')->__('Submit to Riskified'),
138
+ 'onclick' => "deleteConfirm('$message', '$url')",
139
+ ));
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Update the order state and status when it's been updated
145
+ *
146
+ * @param Varien_Event_Observer $observer
147
+ */
148
+ public function updateOrderState(Varien_Event_Observer $observer)
149
+ {
150
+ $riskifiedOrderStatusHelper = Mage::helper('full/order_status');
151
+ $riskifiedInvoiceHelper = Mage::helper('full/order_invoice');
152
+ $order = $observer->getOrder();
153
+ $status = (string) $observer->getStatus();
154
+ $description = (string) $observer->getDescription();
155
+ $newState = $newStatus = null;
156
+ $currentState = $order->getState();
157
+ $currentStatus = $order->getStatus();
158
+
159
+ Mage::helper('full/log')->log("Checking if should update order '" . $order->getId() . "' from state: '$currentState' and status: '$currentStatus'");
160
+
161
+ switch ($status) {
162
+ case 'approved':
163
+ if ($currentState == Mage_Sales_Model_Order::STATE_HOLDED
164
+ && ($currentStatus == $riskifiedOrderStatusHelper->getOnHoldStatusCode()
165
+ || $currentStatus == $riskifiedOrderStatusHelper->getTransportErrorStatusCode())) {
166
+ $newState = Mage_Sales_Model_Order::STATE_PROCESSING;
167
+ $newStatus = TRUE;
168
+ }
169
+
170
+ break;
171
+ case 'declined':
172
+ if ($currentState == Mage_Sales_Model_Order::STATE_HOLDED
173
+ && ($currentStatus == $riskifiedOrderStatusHelper->getOnHoldStatusCode()
174
+ || $currentStatus == $riskifiedOrderStatusHelper->getTransportErrorStatusCode())) {
175
+ $newState = Mage_Sales_Model_Order::STATE_CANCELED;
176
+ $newStatus = Mage_Sales_Model_Order::STATUS_FRAUD;
177
+ }
178
+
179
+ break;
180
+ case 'submitted':
181
+ if ($currentState == Mage_Sales_Model_Order::STATE_PROCESSING
182
+ || ($currentState == Mage_Sales_Model_Order::STATE_HOLDED
183
+ && $currentStatus == $riskifiedOrderStatusHelper->getTransportErrorStatusCode())) {
184
+ $newState = Mage_Sales_Model_Order::STATE_HOLDED;
185
+ $newStatus = $riskifiedOrderStatusHelper->getOnHoldStatusCode();
186
+ }
187
+
188
+ break;
189
+ case 'error':
190
+ if ($currentState == Mage_Sales_Model_Order::STATE_PROCESSING
191
+ && $riskifiedInvoiceHelper->isAutoInvoiceEnabled()) {
192
+ $newState = Mage_Sales_Model_Order::STATE_HOLDED;
193
+ $newStatus = $riskifiedOrderStatusHelper->getTransportErrorStatusCode();
194
+ }
195
+ }
196
+
197
+ $changed = false;
198
+
199
+ // if newState exists and new state/status are different from current and config is set to status-sync
200
+ if ($newState
201
+ && ($newState != $currentState || $newStatus != $currentStatus)
202
+ && Mage::helper('full')->getConfigStatusControlActive()) {
203
+ $order->setState($newState, $newStatus, $description);
204
+ Mage::helper('full/log')->log("Updating order '" . $order->getId() . "' to: state: '$newState', status: '$newStatus', description: '$description'");
205
+ $changed=true;
206
+ } elseif ($description) {
207
+ Mage::helper('full/log')->log("Updating order " . $order->getId() . " history comment to: " . $description);
208
+ $order->addStatusHistoryComment($description);
209
+ $changed=true;
210
+ }
211
+
212
+ if ($changed) {
213
+ try {
214
+ $order->save();
215
+ } catch (Exception $e) {
216
+ Mage::helper('full/log')->log("Error saving order: " . $e->getMessage());
217
+ return;
218
+ }
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Create an invoice when the order is approved
224
+ *
225
+ * @param Varien_Event_Observer $observer
226
+ */
227
+ public function autoInvoice(Varien_Event_Observer $observer)
228
+ {
229
+ $riskifiedInvoiceHelper = Mage::helper('full/order_invoice');
230
+
231
+ if (!$riskifiedInvoiceHelper->isAutoInvoiceEnabled()) {
232
+ return;
233
+ }
234
+
235
+ $order = $observer->getOrder();
236
+
237
+ // Sanity check
238
+ if (!$order || !$order->getId()) {
239
+ return;
240
+ }
241
+
242
+ Mage::helper('full/log')->log("Auto-invoicing order " . $order->getId());
243
+
244
+ if (!$order->canInvoice()) {
245
+ Mage::helper('full/log')->log("Order cannot be invoiced");
246
+ return;
247
+ }
248
+
249
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
250
+
251
+ if (!$invoice->getTotalQty()) {
252
+ Mage::helper('full/log')->log("Cannot create an invoice without products");
253
+ return;
254
+ }
255
+
256
+ try {
257
+ $invoice
258
+ ->setRequestedCaptureCase($riskifiedInvoiceHelper->getCaptureCase())
259
+ ->addComment(
260
+ 'Invoice automatically created by Riskified when order was approved',
261
+ false,
262
+ false
263
+ )
264
+ ->register();
265
+ } catch (Exception $e) {
266
+ Mage::helper('full/log')->log("Error creating invoice: " . $e->getMessage());
267
+ return;
268
+ }
269
+
270
+ try {
271
+ Mage::getModel('core/resource_transaction')
272
+ ->addObject($invoice)
273
+ ->addObject($order)
274
+ ->save();
275
+ } catch (Exception $e) {
276
+ Mage::helper('full/log')->log("Error creating transaction: " . $e->getMessage());
277
+ return;
278
+ }
279
+
280
+ Mage::helper('full/log')->log("Transaction saved");
281
+ }
282
+
283
+ /**
284
+ * Clear all submission retries for an order that have the same action.
285
+ * This event observer is only called after a successful submission.
286
+ *
287
+ * @param Varien_Event_Observer $observer
288
+ */
289
+ public function clearRetriesForOrder(Varien_Event_Observer $observer)
290
+ {
291
+ $order = $observer->getOrder();
292
+
293
+ // Sanity check
294
+ if (!$order || !$order->getId()) {
295
+ return;
296
+ }
297
+
298
+ $retries = Mage::getModel('full/retry')->getCollection()
299
+ ->addfieldtofilter('order_id', $order->getId())
300
+ ->addFieldToFilter('action', $observer->getAction());
301
+
302
+ foreach($retries as $retry) {
303
+ $retry->delete();
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Process the response from a successful post to Riskified.
309
+ *
310
+ * @param Varien_Event_Observer $observer
311
+ */
312
+ public function processSuccessfulPost(Varien_Event_Observer $observer)
313
+ {
314
+ /* @var Mage_Sales_Model_Order $order */
315
+ $order = $observer->getOrder();
316
+
317
+ /* @var stdClass $response */
318
+ $response = $observer->getResponse();
319
+
320
+ if (isset($response->order)) {
321
+ $orderId = $response->order->id;
322
+ $status = $response->order->status;
323
+ $description = $response->order->description;
324
+
325
+ if (!$description) {
326
+ $description = "Riskified Status: $status";
327
+ }
328
+
329
+ if ($orderId && $status) {
330
+ Mage::helper('full/order')->updateOrder($order, $status, $description);
331
+ }
332
+
333
+ $origId = $order->getId();
334
+
335
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__("Order #$origId was successfully updated at Riskified"));
336
+ } else {
337
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__("Malformed response from Riskified"));
338
+ }
339
+ }
340
+ }
app/code/community/Riskified/Full/Model/Resource/Retry.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_Resource_Retry extends Mage_Core_Model_Resource_Db_Abstract
4
+ {
5
+ protected function _construct()
6
+ {
7
+ $this->_init('full/retry', 'retry_id');
8
+ }
9
+ }
app/code/community/Riskified/Full/Model/Resource/Retry/Collection.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_Resource_Retry_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ $this->_init('full/retry');
8
+ }
9
+ }
app/code/community/Riskified/Full/Model/Retry.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_Retry extends Mage_Core_Model_Abstract
4
+ {
5
+ protected function _construct()
6
+ {
7
+ $this->_init('full/retry');
8
+ }
9
+ }
app/code/community/Riskified/Full/Model/System/Config/Source/CaptureCase.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_System_Config_Source_CaptureCase
4
+ {
5
+ /**
6
+ * @return array
7
+ */
8
+ public function toOptionArray()
9
+ {
10
+ return array(
11
+ array('value' => Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE, 'label' => Mage::helper('full')->__('Capture Online')),
12
+ array('value' => Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE, 'label' => Mage::helper('full')->__('Capture Offline'))
13
+ );
14
+ }
15
+ }
app/code/community/Riskified/Full/Model/System/Config/Source/Env.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Model_System_Config_Source_Env
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ return array(
8
+ array('value' => 'PROD', 'label' => Mage::helper('full')->__('Production')),
9
+ array('value' => 'SANDBOX', 'label' => Mage::helper('full')->__('Sandbox')),
10
+ array('value' => 'DEV', 'label' => Mage::helper('full')->__('Dev'))
11
+ );
12
+ }
13
+ }
app/code/community/Riskified/Full/Test/Config/General.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Test_Config_General extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+
6
+ /**
7
+ * Make sure all of our rewrites are in effect
8
+ *
9
+ * @test
10
+ */
11
+ public function testRewrites()
12
+ {
13
+ $this->assertModelAlias('paygate/authorizenet', 'Riskified_Full_Model_Authorizenet');
14
+ }
15
+
16
+ /**
17
+ * Make sure layout files are defined
18
+ *
19
+ * @test
20
+ */
21
+ public function testLayouts()
22
+ {
23
+ $this->assertLayoutFileDefined(
24
+ 'frontend', 'full.xml'
25
+ );
26
+
27
+ $this->assertLayoutFileDefined(
28
+ 'adminhtml', 'full.xml'
29
+ );
30
+ }
31
+
32
+ /**
33
+ * Make sure event observers related to status are properly defined
34
+ *
35
+ * @test
36
+ */
37
+ public function testStatusSyncEventObservers()
38
+ {
39
+ $this->assertEventObserverDefined(
40
+ 'global', 'riskified_full_order_update', 'full/observer', 'updateOrderState'
41
+ );
42
+ }
43
+
44
+ /**
45
+ * Make sure event observers related to auto-invoicing are properly defined
46
+ *
47
+ * @test
48
+ */
49
+ public function testAutoInvoiceEventObservers()
50
+ {
51
+ $this->assertEventObserverDefined(
52
+ 'global', 'riskified_full_order_update_approved', 'full/observer', 'autoInvoice'
53
+ );
54
+
55
+ $this->assertEventObserverDefined(
56
+ 'global', 'riskified_full_order_update_captured', 'full/observer', 'autoInvoice'
57
+ );
58
+ }
59
+ }
app/code/community/Riskified/Full/Test/Helper/General.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Test_Helper_General extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ /**
6
+ * An example test that configures the extension before making any assertions
7
+ *
8
+ * @test
9
+ * @loadFixture extensionConfigEnabled
10
+ */
11
+ public function testConfigurationValuesLoaded()
12
+ {
13
+ $helper = Mage::helper('full');
14
+
15
+ $this->assertEquals(
16
+ $helper->getConfigStatusControlActive(),
17
+ 1
18
+ );
19
+
20
+ $this->assertEquals(
21
+ $helper->getConfigEnv(),
22
+ 'Riskified\Common\Env::DEV'
23
+ );
24
+ }
25
+ }
app/code/community/Riskified/Full/Test/Helper/General/fixtures/extensionConfigEnabled.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ config:
2
+ default/fullsection/full/order_status_sync: 1
3
+ default/fullsection/full/env: DEV
4
+ default/fullsection/full/domain: dev.riskified.com
5
+ default/fullsection/full/key: 123456789
6
+ default/fullsection/full/auto_invoice_enabled: 1
7
+ default/fullsection/full/auto_invoice_capture_case: offline
app/code/community/Riskified/Full/Test/Model/Environments.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once(Mage::getBaseDir('lib') . DIRECTORY_SEPARATOR . 'riskified_php_sdk' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Riskified' . DIRECTORY_SEPARATOR . 'autoloader.php');
4
+
5
+ class Riskified_Full_Test_Model_Environments extends EcomDev_PHPUnit_Test_Case
6
+ {
7
+ /**
8
+ * Test to make sure our environment options exist
9
+ *
10
+ * @test
11
+ */
12
+ public function testEnvironmentsExist()
13
+ {
14
+ $model = Mage::getModel('full/env');
15
+ $environments = $model->toOptionArray();
16
+
17
+ $this->assertEquals(
18
+ count($environments),
19
+ 3
20
+ );
21
+ }
22
+ }
app/code/community/Riskified/Full/controllers/Adminhtml/FullController.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_Adminhtml_FullController extends Mage_Adminhtml_Controller_Action
4
+ {
5
+
6
+ public function riskiAction()
7
+ {
8
+ $id = $this->getRequest()->getParam('order_id');
9
+ $call = Mage::getModel('full/observer');
10
+ $call->postOrderIds(array($id));
11
+
12
+ Mage::app()->getResponse()->setRedirect(Mage::helper('adminhtml')->getUrl("adminhtml/sales_order/index", array('id'=>$id)));
13
+ }
14
+
15
+ public function riskimassAction()
16
+ {
17
+ $order_ids = $this->getRequest()->getParam('order_ids');
18
+ $call = Mage::getModel('full/observer');
19
+ $call->postOrderIds($order_ids);
20
+ Mage::app()->getResponse()->setRedirect(Mage::helper('adminhtml')->getUrl("adminhtml/sales_order/index"));
21
+ }
22
+ }
app/code/community/Riskified/Full/controllers/ResponseController.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Riskified_Full_ResponseController extends Mage_Core_Controller_Front_Action
4
+ {
5
+ public function getresponseAction()
6
+ {
7
+ $request = $this->getRequest();
8
+ $response = $this->getResponse();
9
+ $helper = Mage::helper('full/order');
10
+ $logger = Mage::helper('full/log');
11
+ $statusCode = 200;
12
+ $id = null;
13
+ $msg = null;
14
+
15
+ try {
16
+ $notification = $helper->parseRequest($request);
17
+ $id = $notification->id;
18
+
19
+ Mage::helper('full/log')->log("Notification received: ", serialize($notification));
20
+
21
+ $order = Mage::getModel('sales/order')->load($id);
22
+ if (!$order || !$order->getId()) {
23
+ $logger->log("ERROR: Unable to load order (" . $id . ")");
24
+ $statusCode = 400;
25
+ $msg = 'Could not find order to update.';
26
+ } else {
27
+ $helper->updateOrder($order, $notification->status, $notification->description);
28
+ $statusCode = 200;
29
+ $msg = 'Order-Update event triggered.';
30
+ }
31
+ } catch (Riskified\DecisionNotification\Exception\AuthorizationException $e) {
32
+ $logger->logException($e);
33
+ $statusCode = 401;
34
+ $msg = 'Authentication Failed.';
35
+ } catch (\Riskified\DecisionNotification\Exception\BadPostJsonException $e) {
36
+ $logger->logException($e);
37
+ $statusCode = 400;
38
+ $msg = "JSON Parsing Error.";
39
+ } catch (Exception $e) {
40
+ $logger->log("ERROR: while processing notification for order $id");
41
+ $statusCode = 500;
42
+ $msg = "Internal Error";
43
+ }
44
+
45
+ $response->setHttpResponseCode($statusCode);
46
+ $response->setHeader('Content-Type', 'application/json');
47
+ $response->setBody('{ "order" : { "id" : "' . $id . '", "description" : "' . $msg .'" } }');
48
+
49
+ }
50
+ }
app/code/community/Riskified/Full/etc/config.xml ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Riskified_Full>
5
+ <version>1.0.5.4</version>
6
+ </Riskified_Full>
7
+ </modules>
8
+
9
+ <global>
10
+ <models>
11
+ <paygate>
12
+ <rewrite>
13
+ <authorizenet>Riskified_Full_Model_Authorizenet</authorizenet>
14
+ </rewrite>
15
+ </paygate>
16
+ <full>
17
+ <class>Riskified_Full_Model</class>
18
+ <resourceModel>riskified_full_resource</resourceModel>
19
+ </full>
20
+ <riskified_full_resource>
21
+ <class>Riskified_Full_Model_Resource</class>
22
+ <entities>
23
+ <retry>
24
+ <table>riskified_full_retry</table>
25
+ </retry>
26
+ </entities>
27
+ </riskified_full_resource>
28
+ </models>
29
+ <resources>
30
+ <riskified_full_setup>
31
+ <setup>
32
+ <module>Riskified_Full</module>
33
+ </setup>
34
+ </riskified_full_setup>
35
+ </resources>
36
+ <helpers>
37
+ <full>
38
+ <class>Riskified_Full_Helper</class>
39
+ </full>
40
+ </helpers>
41
+ <events>
42
+ <sales_order_payment_place_start>
43
+ <observers>
44
+ <riskified_full>
45
+ <type>singleton</type>
46
+ <class>full/observer</class>
47
+ <method>saveOrderBefore</method>
48
+ </riskified_full>
49
+ </observers>
50
+ </sales_order_payment_place_start>
51
+ <sales_order_payment_place_end>
52
+ <observers>
53
+ <riskified_full>
54
+ <type>singleton</type>
55
+ <class>full/observer</class>
56
+ <method>salesOrderPaymentPlaceEnd</method>
57
+ </riskified_full>
58
+ </observers>
59
+ </sales_order_payment_place_end>
60
+ <sales_order_payment_void>
61
+ <observers>
62
+ <riskified_full>
63
+ <type>singleton</type>
64
+ <class>full/observer</class>
65
+ <method>salesOrderPaymentVoid</method>
66
+ </riskified_full>
67
+ </observers>
68
+ </sales_order_payment_void>
69
+ <sales_order_payment_refund>
70
+ <observers>
71
+ <riskified_full>
72
+ <type>singleton</type>
73
+ <class>full/observer</class>
74
+ <method>salesOrderPaymentRefund</method>
75
+ </riskified_full>
76
+ </observers>
77
+ </sales_order_payment_refund>
78
+ <sales_order_payment_cancel>
79
+ <observers>
80
+ <riskified_full>
81
+ <type>singleton</type>
82
+ <class>full/observer</class>
83
+ <method>salesOrderPaymentCancel</method>
84
+ </riskified_full>
85
+ </observers>
86
+ </sales_order_payment_cancel>
87
+ <sales_order_place_before>
88
+ <observers>
89
+ <riskified_full>
90
+ <type>singleton</type>
91
+ <class>full/observer</class>
92
+ <method>salesOrderPlaceBefore</method>
93
+ </riskified_full>
94
+ </observers>
95
+ </sales_order_place_before>
96
+ <sales_order_place_after>
97
+ <observers>
98
+ <riskified_full>
99
+ <type>singleton</type>
100
+ <class>full/observer</class>
101
+ <method>salesOrderPlaceAfter</method>
102
+ </riskified_full>
103
+ </observers>
104
+ </sales_order_place_after>
105
+ <sales_order_save_before>
106
+ <observers>
107
+ <riskified_full>
108
+ <type>singleton</type>
109
+ <class>full/observer</class>
110
+ <method>salesOrderSaveBefore</method>
111
+ </riskified_full>
112
+ </observers>
113
+ </sales_order_save_before>
114
+ <sales_order_save_after>
115
+ <observers>
116
+ <riskified_full>
117
+ <type>singleton</type>
118
+ <class>full/observer</class>
119
+ <method>salesOrderSaveAfter</method>
120
+ </riskified_full>
121
+ </observers>
122
+ </sales_order_save_after>
123
+ <order_cancel_after>
124
+ <observers>
125
+ <riskified_full>
126
+ <type>singleton</type>
127
+ <class>full/observer</class>
128
+ <method>salesOrderCancel</method>
129
+ </riskified_full>
130
+ </observers>
131
+ </order_cancel_after>
132
+ <adminhtml_widget_container_html_before>
133
+ <observers>
134
+ <module>
135
+ <type>singleton</type>
136
+ <class>full/observer</class>
137
+ <method>blockHtmlBefore</method>
138
+ </module>
139
+ </observers>
140
+ </adminhtml_widget_container_html_before>
141
+ <riskified_full_order_update>
142
+ <observers>
143
+ <riskified_full_handle_order_update>
144
+ <class>full/observer</class>
145
+ <method>updateOrderState</method>
146
+ </riskified_full_handle_order_update>
147
+ </observers>
148
+ </riskified_full_order_update>
149
+ <riskified_full_order_update_approved>
150
+ <observers>
151
+ <riskified_full_handle_order_update_approved>
152
+ <class>full/observer</class>
153
+ <method>autoInvoice</method>
154
+ </riskified_full_handle_order_update_approved>
155
+ </observers>
156
+ </riskified_full_order_update_approved>
157
+ <riskified_full_order_update_captured>
158
+ <observers>
159
+ <riskified_full_handle_order_update_captured>
160
+ <class>full/observer</class>
161
+ <method>autoInvoice</method>
162
+ </riskified_full_handle_order_update_captured>
163
+ </observers>
164
+ </riskified_full_order_update_captured>
165
+ <riskified_full_post_order_success>
166
+ <observers>
167
+ <riskified_full_clear_retries>
168
+ <class>full/observer</class>
169
+ <method>clearRetriesForOrder</method>
170
+ </riskified_full_clear_retries>
171
+ <riskified_full_process_successful_post>
172
+ <class>full/observer</class>
173
+ <method>processSuccessfulPost</method>
174
+ </riskified_full_process_successful_post>
175
+ </observers>
176
+ </riskified_full_post_order_success>
177
+ </events>
178
+ </global>
179
+
180
+ <frontend>
181
+ <routers>
182
+ <full>
183
+ <use>standard</use>
184
+ <args>
185
+ <module>Riskified_Full</module>
186
+ <frontName>full</frontName>
187
+ </args>
188
+ </full>
189
+ </routers>
190
+ <layout>
191
+ <updates>
192
+ <full>
193
+ <file>full.xml</file>
194
+ </full>
195
+ </updates>
196
+ </layout>
197
+ </frontend>
198
+
199
+ <admin>
200
+ <routers>
201
+ <full>
202
+ <use>admin</use>
203
+ <args>
204
+ <module>Riskified_Full</module>
205
+ <frontName>full</frontName>
206
+ </args>
207
+ </full>
208
+ </routers>
209
+ </admin>
210
+
211
+ <adminhtml>
212
+ <acl>
213
+ <resources>
214
+ <all>
215
+ <title>Allow Everything</title>
216
+ </all>
217
+ <admin>
218
+ <children>
219
+ <Riskified_Full>
220
+ <title>Full Module</title>
221
+ <sort_order>10</sort_order>
222
+ </Riskified_Full>
223
+ <system>
224
+ <children>
225
+ <config>
226
+ <children>
227
+ <fullsection translate="title"
228
+ module="full"> <!-- This is name of the section created by us -->
229
+ <title>Riskified</title>
230
+ <!-- Title as shown in User->Roles->Permissions Window -->
231
+ <sort_order>99</sort_order>
232
+ </fullsection>
233
+ </children>
234
+ </config>
235
+ </children>
236
+ </system>
237
+ </children>
238
+ </admin>
239
+ </resources>
240
+ </acl>
241
+ <layout>
242
+ <updates>
243
+ <full>
244
+ <file>full.xml</file>
245
+ </full>
246
+ </updates>
247
+ </layout>
248
+ <events>
249
+ <core_block_abstract_prepare_layout_before>
250
+ <observers>
251
+ <before_grid_prep>
252
+ <type>singleton</type>
253
+ <class>Riskified_Full_Model_Observer</class>
254
+ <method>addMassAction</method>
255
+ </before_grid_prep>
256
+ </observers>
257
+ </core_block_abstract_prepare_layout_before>
258
+ </events>
259
+ </adminhtml>
260
+
261
+ <crontab>
262
+ <jobs>
263
+ <riskified_full_retry_submission>
264
+ <schedule>
265
+ <cron_expr>*/5 * * * *</cron_expr>
266
+ </schedule>
267
+ <run>
268
+ <model>full/cron::retrySubmissions</model>
269
+ </run>
270
+ </riskified_full_retry_submission>
271
+ </jobs>
272
+ </crontab>
273
+
274
+ <phpunit>
275
+ <suite>
276
+ <modules>
277
+ <Riskified_Full />
278
+ </modules>
279
+ </suite>
280
+ </phpunit>
281
+
282
+ <default>
283
+ <fullsection>
284
+ <full>
285
+ <order_status_sync>0</order_status_sync>
286
+ <env>PROD</env>
287
+ <beaconurl>beacon.riskified.com</beaconurl>
288
+ <auto_invoice_enabled>0</auto_invoice_enabled>
289
+ <auto_invoice_capture_case>online</auto_invoice_capture_case>
290
+ </full>
291
+ </fullsection>
292
+ </default>
293
+ </config>
app/code/community/Riskified/Full/etc/system.xml ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <newtab translate="label" module="full">
5
+ <label>Riskified</label>
6
+ <sort_order>999</sort_order>
7
+ </newtab>
8
+ </tabs>
9
+
10
+ <sections>
11
+ <fullsection translate="label" module="full">
12
+ <class>separator-top</class>
13
+ <label>Settings</label>
14
+ <tab>newtab</tab>
15
+ <sort_order>130</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <groups>
20
+ <full translate="label">
21
+ <label>API settings</label>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>0</show_in_website>
25
+ <show_in_store>0</show_in_store>
26
+ <fields>
27
+ <order_status_sync translate="label comment">
28
+ <label>Order Status Sync</label>
29
+ <comment><![CDATA[ Enable/Disable automatic changes to Order status by Riskified's review process.
30
+ <br>Requires the <i>Order notification endpoint</i> to be configured correctly in your Riskified Settings page.
31
+ <br>Using the following mapping:
32
+ <br>'submit' => 'on hold' <br>'approve' => 'processing'<br>'decline' => 'canceled'
33
+ <br><b>Important:</b> Might affect other extensions that are dependent on an Order's status.
34
+ ]]></comment>
35
+ <frontend_type>select</frontend_type>
36
+ <sort_order>1</sort_order>
37
+ <show_in_default>1</show_in_default>
38
+ <show_in_website>1</show_in_website>
39
+ <show_in_store>1</show_in_store>
40
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
41
+ </order_status_sync>
42
+ <env translate="label comment">
43
+ <label>Riskified environment</label>
44
+ <frontend_type>select</frontend_type>
45
+ <source_model>full/system_config_source_env</source_model>
46
+ <sort_order>2</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ <comment><![CDATA[Select Riskified's environment.<br> You can use sandbox for testing.
51
+ <br>If you don't have a sandbox account please contact support@riskified.com ]]></comment>
52
+ </env>
53
+ <!--<activationstatus>
54
+ <comment></comment>
55
+ <frontend_type>text</frontend_type>
56
+ <sort_order>4</sort_order>
57
+ <class>riskified_activationstatus</class>
58
+ <show_in_default>1</show_in_default>
59
+ <show_in_website>1</show_in_website>
60
+ <show_in_store>1</show_in_store>
61
+ </activationstatus>-->
62
+ <domain translate="label comment">
63
+ <label>Shop Domain</label>
64
+ <frontend_type>Text</frontend_type>
65
+ <sort_order>5</sort_order>
66
+ <show_in_default>1</show_in_default>
67
+ <show_in_website>1</show_in_website>
68
+ <show_in_store>1</show_in_store>
69
+ <comment><![CDATA[This is your Riskified's account username]]></comment>
70
+ </domain>
71
+ <key translate="label comment">
72
+ <label>Auth token</label>
73
+ <frontend_type>Text</frontend_type>
74
+ <sort_order>6</sort_order>
75
+ <show_in_default>1</show_in_default>
76
+ <show_in_website>1</show_in_website>
77
+ <show_in_store>1</show_in_store>
78
+ <comment><![CDATA[ Your <i>secret</i> auth token can be found in your Riskified Settings page. ]]></comment>
79
+ </key>
80
+
81
+ <auto_invoice_enabled translate="label comment">
82
+ <label>Enable Auto-Invoice</label>
83
+ <frontend_type>select</frontend_type>
84
+ <source_model>adminhtml/system_config_source_yesno</source_model>
85
+ <sort_order>110</sort_order>
86
+ <show_in_default>1</show_in_default>
87
+ <show_in_website>0</show_in_website>
88
+ <show_in_store>0</show_in_store>
89
+ <comment><![CDATA[Should an invoice automatically be created when Riskified approves this order?]]></comment>
90
+ <depends>
91
+ <order_status_sync>1</order_status_sync>
92
+ </depends>
93
+ </auto_invoice_enabled>
94
+ <auto_invoice_capture_case translate="label comment">
95
+ <label>Auto-Invoice Capture Case</label>
96
+ <frontend_type>select</frontend_type>
97
+ <source_model>full/system_config_source_captureCase</source_model>
98
+ <sort_order>120</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>0</show_in_website>
101
+ <show_in_store>0</show_in_store>
102
+ <comment><![CDATA[Should this invoice be captured online or offline?]]></comment>
103
+ <depends>
104
+ <order_status_sync>1</order_status_sync>
105
+ </depends>
106
+ </auto_invoice_capture_case>
107
+ </fields>
108
+ </full>
109
+ </groups>
110
+ </fullsection>
111
+ </sections>
112
+ </config>
app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-install-1.0.1.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Mage_Core_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $helper = Mage::helper('full/order_status');
8
+
9
+ Mage::getModel('sales/order_status')
10
+ ->setStatus($helper->getOnHoldStatusCode())->setLabel($helper->getOnHoldStatusLabel())
11
+ ->assignState(Mage_Sales_Model_Order::STATE_HOLDED)
12
+ ->save();
13
+
14
+ $installer->endSetup();
app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-install-1.0.2.1.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Mage_Core_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $helper = Mage::helper('full/order_status');
8
+
9
+ Mage::getModel('sales/order_status')
10
+ ->setStatus($helper->getTransportErrorStatusCode())->setLabel($helper->getTransportErrorStatusLabel())
11
+ ->assignState(Mage_Sales_Model_Order::STATE_HOLDED)
12
+ ->save();
13
+
14
+ $installer->endSetup();
app/code/community/Riskified/Full/sql/riskified_full_setup/mysql4-upgrade-1.0.4-1.0.5.0.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* @var $installer Mage_Core_Model_Resource_Setup */
4
+ $installer = $this;
5
+
6
+ $installer->startSetup();
7
+
8
+ $table = $installer->getConnection()
9
+ ->newTable($installer->getTable('full/retry'))
10
+ ->addColumn('retry_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
11
+ 'identity' => true,
12
+ 'unsigned' => true,
13
+ 'nullable' => false,
14
+ 'primary' => true,
15
+ ), 'Id')
16
+ ->addColumn('order_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
17
+ 'unsigned' => true,
18
+ 'nullable' => false,
19
+ 'default' => 0
20
+ ), 'Order Id')
21
+ ->addColumn('action', Varien_Db_Ddl_Table::TYPE_VARCHAR, null, array(
22
+ 'nullable' => false,
23
+ ), 'Action')
24
+ ->addColumn('last_error', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
25
+ 'nullable' => true,
26
+ ), 'Last Error')
27
+ ->addColumn('attempts', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
28
+ 'unsigned' => true,
29
+ 'nullable' => false,
30
+ 'default' => 0
31
+ ), 'Number of retry attempts')
32
+ ->addColumn('updated_at', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array(
33
+ 'nullable' => false
34
+ ), 'Date last updated')
35
+ ;
36
+
37
+ $installer->getConnection()->createTable($table);
38
+
39
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/full.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <adminhtml_system_config_edit>
4
+ <reference name="content">
5
+ <block type="core/template" name="full_jsinit" template="full/jsinit.phtml"></block>
6
+ </reference>
7
+ </adminhtml_system_config_edit>
8
+ </layout>
app/design/adminhtml/default/default/template/full/jsinit.phtml ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category design
16
+ * @package default_default
17
+ * @copyright Copyright (c) 2011 Riskified (http://www.riskified.com)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+ ?>
21
+
22
+ <?php
23
+ $all_active_methods = Mage::getModel('payment/config')->getActiveMethods();
24
+ $allkeys ='';
25
+ foreach ($all_active_methods as $key => $value)
26
+ {
27
+ $paymentTitle = Mage::getStoreConfig('payment/'.$key.'/title');
28
+ $methods[$key] = $paymentTitle;
29
+ $allkeys .= $key.",";
30
+ }
31
+ ?>
32
+
33
+ <style type="text/css">
34
+ .riskified-botton {
35
+ font-family: Helvetica Neue;
36
+ font-size: 23px;
37
+ line-height: 25px;
38
+ color: #FFF;
39
+ background-color: #9bc47f;
40
+ background: #9bc47f;
41
+ padding: 5px 10px;
42
+ border: 1px solid #828282;
43
+ display: inline-block;
44
+ text-decoration: none;
45
+ width: 294px;
46
+ text-align: center;
47
+ font-weight: 300;
48
+ letter-spacing: 0.05em;
49
+ margin-bottom: 20px;
50
+ }
51
+
52
+ .riskified-botton:hover{
53
+ background-color: #edd364;
54
+ background: #edd364;
55
+ text-decoration: none;
56
+ color: #FFF;
57
+ }
58
+
59
+ .step-inner {
60
+ display: inline-block;
61
+ vertical-align: top;
62
+ float: right;
63
+ }
64
+
65
+ .step-action {
66
+ display: inline-block;
67
+ float: right;
68
+ }
69
+
70
+ .step-wrapper {
71
+ margin-top: 30px;
72
+ padding-top: 30px;
73
+ border-top: 1px solid #dedede;
74
+ display: block;
75
+ width: 800px;
76
+ clear: both;
77
+ }
78
+ #activate-form input{
79
+ display: block;
80
+ width: 300px;
81
+ line-height: 30px;
82
+ font-size: 17px;
83
+ margin-bottom: 10px;
84
+ padding-left: 10px ;
85
+ }
86
+
87
+ .text-notice {
88
+ font-weight: 300;
89
+ font-size: 15px;
90
+ color: #d15a2f;
91
+ display: none;
92
+ margin-top: 0px;
93
+ margin-bottom: 0px;
94
+ line-height: 0px;
95
+ text-align: center;
96
+ }
97
+
98
+ #activation-done{
99
+ display: none;
100
+ }
101
+
102
+ </style>
103
+
104
+ <script type="text/javascript">
105
+ //<![CDATA[
106
+
107
+ function showRiskifiedNotice(noticeId){
108
+ $$(noticeId)[0].style.setProperty("display","block");
109
+ }
110
+
111
+ function hideRiskifiedNotice(noticeId){
112
+ $$(noticeId)[0].style.setProperty("display","none");
113
+ }
114
+
115
+ function activate(){
116
+ var riskifiedShopDomain = $$("#riskified-shop-domain")[0].value;
117
+ if (riskifiedShopDomain == ""){
118
+ showRiskifiedNotice("#magento-notice");
119
+ return;
120
+ }
121
+ var riskifiedPassword = $$("#riskified-shop-password")[0].value;
122
+
123
+ if (riskifiedPassword == ""){
124
+ showRiskifiedNotice("#magento-notice");
125
+ return;
126
+ }
127
+
128
+ var generatedKey = "<?php echo sha1(microtime(true).mt_rand(10000,90000)); ?>";
129
+
130
+ $$("#fullsection_full_key")[0].value = generatedKey;
131
+ $$("#fullsection_full_domain")[0].value = riskifiedShopDomain;
132
+ riskifiedActivation(riskifiedPassword,riskifiedShopDomain,generatedKey)
133
+ }
134
+
135
+ function riskifiedOnSave(event){
136
+ try
137
+ {
138
+ var fullsectionIndex = document.location.href.indexOf('fullsection');
139
+ if (fullsectionIndex == -1){
140
+ return;
141
+ }
142
+ var riskifiedShopDomain = '<?php echo Mage::helper("full")->getShopDomain()?>'
143
+ var generatedKey = '<?php echo Mage::helper('full')->getAuthToken()?>';
144
+
145
+ var version = "<?php echo Mage::helper('full')->getExtensionVersion() ?>";
146
+ var extensionConfigSaveEndpoint = ('https:' == document.location.protocol ? 'https://' : 'http://') + '<?php echo Mage::helper("full/order")->getRiskifiedDomain()?>/magento/config';
147
+ var admin_url = '<?php echo Mage::helper("full")->getAdminUrl()?>';
148
+
149
+ new Ajax.Request(extensionConfigSaveEndpoint, {
150
+ method: 'POST',
151
+ parameters: "shop_url="+riskifiedShopDomain+"&auth_token="+generatedKey+"&admin_url="+admin_url+"&version"+version
152
+ });
153
+ }catch(err){
154
+ console.log("error reporting new config params");
155
+ }
156
+ return true;
157
+ }
158
+
159
+ function riskifiedActivation(riskifiedPassword,riskifiedShopDomain,generatedKey){
160
+ var keys = "<?php echo $allkeys ?>";
161
+ var activateURL = 'https://' + '<?php echo Mage::helper("full/order")->getRiskifiedDomain()?>/magento/activate';
162
+
163
+ new Ajax.Request(activateURL, {
164
+ method: 'POST',
165
+ parameters: "shop_url="+riskifiedShopDomain+"&password="+riskifiedPassword+"&auth_token="+generatedKey+"&gws="+keys ,
166
+ onSuccess:
167
+ function(response) {
168
+ hideRiskifiedNotice("#magento-notice");
169
+ configForm.submit();
170
+ $$("#activation-done")[0].style.setProperty("display","block");
171
+ $$("#activation-pre")[0].style.setProperty("display","none");
172
+ $$("#activate_button")[0].disabled = true;
173
+ },
174
+ onFailure:
175
+ function(response) {
176
+ showRiskifiedNotice("#magento-notice");
177
+ }
178
+ });
179
+ }
180
+ document.observe("dom:loaded", function() {
181
+ var rhtml = '';
182
+ rhtml += '<span id="riskified-logo" style="margin-top: 12px; margin-bottom: 19px; display:block">';
183
+ rhtml += ' <img width="204px" height="53px" src="<?php echo $this->getSkinUrl('images/riskified/logo.jpg'); ?>"/>';
184
+ rhtml += '</span>';
185
+ rhtml += '<div id="riskified-header" style="font-family:Helvetica Neue; font-size: 19px; line-height: 23px; color: #393536;">';
186
+ rhtml += 'The Riskified extension has been installed.<br>To activate the extension please connect it to your Riskified account';
187
+ rhtml += '</div>';
188
+ rhtml += '<span class="step-wrapper">';
189
+ rhtml += ' <div class="step-title" style="font-family:Helvetica Neue; font-size: 25px; line-height: 30px; color: #393536; display:inline-block">';
190
+ rhtml += ' 1. Create Your Account';
191
+ rhtml += ' <span style="margin-left: 20px;font-family:Helvetica Neue; font-size: 14px; line-height: 17px; color: #828282; padding: 5px; display:block">';
192
+ rhtml += ' Already have an account? go to step #2';
193
+ rhtml += ' </span>';
194
+ rhtml += ' </div>';
195
+ rhtml += ' <span class="step-inner">';
196
+ rhtml += ' <span class="step-action">';
197
+ rhtml += ' <a class="riskified-botton" style="margin-top:13px" href="http://www.riskified.com/?platform=magento#install-section" target="_blank">Create an account</a>';
198
+ rhtml += ' </span>';
199
+ rhtml += ' </span>';
200
+ rhtml += '</span>';
201
+ rhtml += '<span class="step-wrapper">';
202
+ rhtml += ' <div class="step-title" style="font-family:Helvetica Neue; font-size: 25px; line-height: 30px; color: #393536; display:inline-block">';
203
+ rhtml += ' 2. Activate you extension';
204
+ rhtml += ' </div>';
205
+ rhtml += ' <span class="step-inner" id="activation-pre">';
206
+ rhtml += ' <form id="activate-form">';
207
+ rhtml += ' <input tabindex="1" id="riskified-shop-domain" type="text" pattern="" placeholder="your-riskified.shop.domain">';
208
+ rhtml += ' <input tabindex="2" id="riskified-shop-password" type="password" pattern="" placeholder="your Riskified password">';
209
+ rhtml += ' </form>';
210
+ rhtml += ' <span class="text-notice" id="magento-notice">Shop url or password are incorrect</span>';
211
+ rhtml += ' <span class="step-action">';
212
+ rhtml += ' <a tabindex="3" class="riskified-botton" href="javascript:activate()">Activate your account</a>';
213
+ rhtml += ' </span>';
214
+ rhtml += ' </span>';
215
+ rhtml += ' <span class="step-inner" id="activation-done">';
216
+ rhtml += ' <span class="step-action">';
217
+ rhtml += ' <span class="done-message" style="display:block; margin-bottom:25; text-align:center; font-family:Helvetica Neue; font-size: 25px; line-height: 30px; color: #9bc47f;">Activation was successfull</span>';
218
+ rhtml += ' <span class="done-message" style="display:block; margin-bottom:25; text-align:center; font-family:Helvetica Neue; font-size: 25px; line-height: 30px; color: #828282;">Saving...</span>';
219
+ rhtml += ' </span>';
220
+ rhtml += ' </span>';
221
+ rhtml += '</span>';
222
+
223
+ rhtml += '</span>';
224
+ var keyRow = $$('#row_fullsection_full_key')
225
+ if (keyRow.size()== 0){
226
+ return;
227
+ }else{
228
+ keyRow = keyRow[0];
229
+ }
230
+
231
+ var authToken = '<?php echo Mage::helper('full')->getAuthToken()?>';
232
+
233
+ var section = $$("#fullsection_full")[0];
234
+
235
+ if (authToken.trim()) {
236
+ rhtml = '<span id="riskified-logo" style="margin-top: 12px; margin-bottom: 19px; display:block"> <img width="204px" height="53px" src="<?php echo $this->getSkinUrl('images/riskified/logo.jpg'); ?>"></span>';
237
+ rhtml += '<div id="riskified-header" style="font-family:Helvetica Neue; font-size: 19px; line-height: 23px; color: #393536;margin-bottom: 25px;">The extension is connected to your Riskified account</div>';
238
+ rhtml += '<a class="riskified-botton" style="margin-bottom:30px" href="//<?php echo Mage::helper('full/order')->getRiskifiedDomain()?>" target="_blank">Go to Riskified App</a>';
239
+ }else{
240
+ section.style.display = "none";
241
+ $$(".entry-edit-head.collapseable")[0].style.display = "none";
242
+ }
243
+ htmlBody = rhtml;
244
+
245
+ section.up().insert({top:htmlBody});
246
+ $$(".save").forEach(function(saveButton){saveButton.observe('click',riskifiedOnSave)})
247
+ });
248
+
249
+ //]]>
250
+ </script>
251
+
app/design/frontend/base/default/layout/full.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="before_body_end">
5
+ <block type="core/template" name="riskified_analytics" as="riskified_analytics" template="full/riskified.phtml" />
6
+ </reference>
7
+ </default>
8
+ </layout>
9
+
app/design/frontend/base/default/template/full/riskified.phtml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <script type="text/javascript">
3
+ (function() {
4
+ function riskifiedBeaconLoad() {
5
+ var session_id = "<?php echo Mage::helper('full')->getSessionId(); ?>";
6
+ var store_domain="<?php echo Mage::helper('full')->getShopDomain() ?>";
7
+ var statusControlActive = "<?php echo Mage::helper('full')->getConfigStatusControlActive() ?>";
8
+ var version = "<?php echo Mage::helper('full')->getExtensionVersion() ?>";
9
+ var url = ('https:' == document.location.protocol ? 'https://' : 'http://') + "<?php echo Mage::helper('full')->getConfigBeaconUrl()?>?shop="+store_domain+"&sid="+session_id+"&v="+version;
10
+ var s = document.createElement('script');
11
+ s.type = 'text/javascript';
12
+ s.async = true;
13
+ s.src = url;
14
+ var x = document.getElementsByTagName('script')[0];
15
+ x.parentNode.insertBefore(s, x);
16
+ }
17
+ window.attachEvent ? window.attachEvent('onload', riskifiedBeaconLoad) : window.addEventListener('load', riskifiedBeaconLoad, false);
18
+ })();
19
+ </script>
app/etc/modules/Riskified_Full.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Riskified_Full>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Riskified_Full>
8
+ </modules>
9
+ </config>
lib/riskified_php_sdk/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ doc/*
2
+ vendor/*
3
+ .idea/*
lib/riskified_php_sdk/README.md ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Riskified PHP SDK
2
+ =================
3
+
4
+ See *samples/* for examples on how to use this SDK.
5
+
6
+ Migrating to API Version 2
7
+ --------------------------
8
+
9
+ API Version 2 introduces new features (and breaks some old ones).
10
+
11
+ ### Order Webhook ###
12
+
13
+ This version represents a shift from data-driven order handling to multiple API endpoints, each designed
14
+ for a specific purpose. These include:
15
+
16
+ * `/api/create` - served by `$transport->createOrder()`
17
+ * `/api/update` - served by `$transport->updateOrder()`
18
+ * `/api/submit` - served by `$transport->submitOrder()`
19
+ * `/api/refund` - served by `$transport->refundOrder()`
20
+ * `/api/cancel` - served by `$transport->cancelOrder()`
21
+
22
+ Refer to the online [documentation](http://apiref.riskified.com) for more details.
23
+ When migrating from version 1, you'll need to separate the different calls to Riskified's API to support this new process.
24
+
25
+
26
+ ### Decision Notifications ###
27
+
28
+ #### Constructor $headers argument format ####
29
+ The format of the `$headers` argument when constructing a new `Riskified\DecisionNotification\Notification` instance has changed.
30
+ The constructor now expects an associative array of all the HTTP headers of the request, and *not* a flat array of strings, as
31
+ in previous versions of this SDK.
32
+
33
+ This change should simplify integration since the argument now follows the format of the return value of the popular PHP/Apache
34
+ function [`getallheaders()`](http://php.net/manual/en/function.getallheaders.php).
35
+
36
+
37
+ #### API v2 payload format ####
38
+ Notification requests in API version 2 now contain a JSON encoded payload which is more flexible and easily extended.
39
+
40
+ If you are already using the `Notification` class in version 1, there are no additional actions required to support the
41
+ migration to JSON, as this SDK handles the new data format seamlessly.
42
+
43
+
44
+
45
+
46
+
lib/riskified_php_sdk/sample/callback.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ // Router handler for callback server
18
+ // See run_callback_server.sh for usage
19
+
20
+ include __DIR__.'/../src/Riskified/autoloader.php';
21
+ use Riskified\Common\Riskified;
22
+ use Riskified\Common\Signature;
23
+ use Riskified\DecisionNotification\Model;
24
+
25
+ # Replace with the 'shop domain' of your account in Riskified
26
+ $domain = "test.com";
27
+
28
+ # Replace with the 'auth token' listed in the Riskified web app under the 'Settings' Tab
29
+ $authToken = "1388add8a99252fc1a4974de471e73cd";
30
+
31
+ Riskified::init($domain, $authToken);
32
+
33
+ $signature = new Signature\HttpDataSignature();
34
+
35
+ $valid_headers = array(
36
+ $signature::HMAC_HEADER_NAME
37
+ );
38
+
39
+ function map_keys($header, $value) {
40
+ $canonical_header = str_replace('HTTP-','', str_replace('_', '-', strtoupper(trim($header))));
41
+ return array ($canonical_header => $value);
42
+ };
43
+
44
+ function reduce_keys($carry, $item) {
45
+ if (is_null($carry)) {
46
+ $carry=array();
47
+ }
48
+ return array_merge($carry, $item);
49
+ };
50
+
51
+ $canonical_headers = array_reduce(array_map('map_keys', array_keys($_SERVER), $_SERVER), 'reduce_keys');
52
+
53
+ $body = @file_get_contents('php://input');
54
+ $headers = array_intersect_key($canonical_headers, array_flip($valid_headers));
55
+
56
+ $notification = new Model\Notification($signature, $headers, $body);
57
+ $msg = "Order #$notification->id changed to status '$notification->status' with message '$notification->description'\n";
58
+
59
+ $output = fopen('php://stdout', 'w');
60
+ fputs($output, $msg);
61
+ fclose($output);
62
+
63
+ return true;
lib/riskified_php_sdk/sample/order_webhook.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ // A simple example of creating an order from the command line.
18
+ // Usage: php order_webhook.php
19
+
20
+ include __DIR__.'/../src/Riskified/autoloader.php';
21
+ use Riskified\Common\Riskified;
22
+ use Riskified\Common\Env;
23
+ use Riskified\Common\Signature;
24
+ use Riskified\OrderWebhook\Model;
25
+ use Riskified\OrderWebhook\Transport;
26
+
27
+ # Replace with the 'shop domain' of your account in Riskified
28
+ $domain = "test.com";
29
+
30
+ # Replace with the 'auth token' listed in the Riskified web app under the 'Settings' Tab
31
+ $authToken = "1388add8a99252fc1a4974de471e73cd";
32
+
33
+ Riskified::init($domain, $authToken, Env::SANDBOX);
34
+
35
+ # Order
36
+ $order = new Model\Order(array(
37
+ 'id' => '1234',
38
+ 'name' => '#1234',
39
+ 'email' => 'great.customer@example.com',
40
+ 'created_at' => '2010-01-10T11:00:00-05:00',
41
+ 'closed_at' => null,
42
+ 'currency' => 'CAD',
43
+ 'updated_at' => '2010-01-10T11:00:00-05:00',
44
+ 'gateway' => 'mypaymentprocessor',
45
+ 'browser_ip' => '124.185.86.55',
46
+ 'total_price' => 113.23,
47
+ 'total_discounts' => 5.0,
48
+ 'cart_token' => '1sdaf23j212',
49
+ 'additional_emails' => array('my@email.com','second@email.co.uk'),
50
+ 'note' => 'Shipped to my hotel.',
51
+ 'referring_site' => 'google.com'
52
+ ));
53
+
54
+ # LineItems
55
+ $lineItem1 = new Model\LineItem(array(
56
+ 'price' => 100,
57
+ 'quantity' => 1,
58
+ 'title' => 'ACME Widget',
59
+ 'product_id' => '101',
60
+ 'sku' => 'ABCD'
61
+ ));
62
+
63
+ $lineItem2 = new Model\LineItem(array(
64
+ 'price' => 200,
65
+ 'quantity' => 4,
66
+ 'title' => 'ACME Spring',
67
+ 'product_id' => '202',
68
+ 'sku' => 'EFGH'
69
+ ));
70
+ $order->line_items = array($lineItem1, $lineItem2);
71
+
72
+ # DiscountCodes
73
+ $discountCode = new Model\DiscountCode(array(
74
+ 'amount' => 19.95,
75
+ 'code' => '12'
76
+ ));
77
+ $order->discount_codes = $discountCode;
78
+
79
+ # ShippingLines
80
+ $shippingLine = new Model\ShippingLine(array(
81
+ 'price' => 123.00,
82
+ 'title' => 'Free',
83
+ ));
84
+ $order->shipping_lines = $shippingLine;
85
+
86
+ # PaymentDetais
87
+ $paymentDetails = new Model\PaymentDetails(array(
88
+ 'credit_card_bin' => '370002',
89
+ 'avs_result_code' => 'Y',
90
+ 'cvv_result_code' => 'N',
91
+ 'credit_card_number' => 'xxxx-xxxx-xxxx-1234',
92
+ 'credit_card_company' => 'VISA'
93
+ ));
94
+ $order->payment_details = $paymentDetails;
95
+
96
+ # Customer
97
+ $customer = new Model\Customer(array(
98
+ 'email' => 'email@address.com',
99
+ 'first_name' => 'Firstname',
100
+ 'last_name' => 'Lastname',
101
+ 'id' => '1233',
102
+ 'created_at' => '2008-01-10T11:00:00-05:00',
103
+ 'orders_count' => 6,
104
+ 'verified_email' => true
105
+ ));
106
+ $order->customer = $customer;
107
+
108
+ # BillingAddress
109
+ $billingAddress = new Model\Address(array(
110
+ 'first_name' => 'John',
111
+ 'last_name' => 'Doe',
112
+ 'address1' => '108 Main Street',
113
+ 'company' => 'Kansas Computers',
114
+ 'country' => 'United States',
115
+ 'country_code' => 'US',
116
+ 'phone' => '1234567',
117
+ 'city' => 'NYC',
118
+ 'name' => 'John Doe',
119
+ 'address2' => 'Apartment 12',
120
+ 'province' => 'New York',
121
+ 'province_code' => 'NY',
122
+ 'zip' => '64155'
123
+ ));
124
+ $order->billing_address = $billingAddress;
125
+
126
+ # ShippingAddress
127
+ $shippingAddress = new Model\Address(array(
128
+ 'first_name' => 'John',
129
+ 'last_name' => 'Doe',
130
+ 'address1' => '108 Main Street',
131
+ 'company' => 'Kansas Computers',
132
+ 'country' => 'United States',
133
+ 'country_code' => 'US',
134
+ 'phone' => '1234567',
135
+ 'city' => 'NYC',
136
+ 'name' => 'John Doe',
137
+ 'address2' => 'Apartment 12',
138
+ 'province' => 'New York',
139
+ 'province_code' => 'NY',
140
+ 'zip' => '64155'
141
+ ));
142
+ $order->shipping_address = $shippingAddress;
143
+
144
+ echo "\nREQUEST:".PHP_EOL.json_encode(json_decode($order->toJson())).PHP_EOL;
145
+
146
+ # Create a curl transport to the Riskified Server
147
+ $transport = new Transport\CurlTransport(new Signature\HttpDataSignature());
148
+ $transport->timeout = 10;
149
+
150
+ try {
151
+ $response = $transport->createOrder($order);
152
+ echo PHP_EOL."Create Order succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
153
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
154
+ echo PHP_EOL."Create order not succeeded. Status code was: ".$uae->statusCode." and json body was: "
155
+ .json_encode($uae->jsonResponse).PHP_EOL;
156
+ } catch(Exception $e) {
157
+ echo PHP_EOL."Create order not succeeded. Exception: ".$e->getMessage().PHP_EOL;
158
+ }
159
+
160
+ try {
161
+ $response = $transport->submitOrder($order);
162
+ echo PHP_EOL."Submit order succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
163
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
164
+ echo PHP_EOL."Submit order not succeeded. Status code was: ".$uae->statusCode." and json body was: "
165
+ .json_encode($uae->jsonResponse).PHP_EOL;
166
+ } catch(Exception $e) {
167
+ echo PHP_EOL."Submit order not succeeded. Exception: ".$e->getMessage().PHP_EOL;
168
+ }
169
+
170
+ $updatedOrder = new Model\Order(array(
171
+ 'id' => $order->id,
172
+ 'email' => 'another.email@example.com',
173
+ ));
174
+
175
+ try {
176
+ $response = $transport->updateOrder($updatedOrder);
177
+ echo PHP_EOL."Update Order succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
178
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
179
+ echo PHP_EOL."Update order not succeeded. Status code was: ".$uae->statusCode." and json body was: "
180
+ .json_encode($uae->jsonResponse).PHP_EOL;
181
+ } catch(Exception $e) {
182
+ echo PHP_EOL."Update order not succeeded. Exception: ".$e->getMessage().PHP_EOL;
183
+ }
184
+
185
+ $refund = new Model\Refund(array(
186
+ 'id' => $order->id,
187
+ 'refunds' => array(new Model\RefundDetails(array(
188
+ 'refund_id' => 'refund_001',
189
+ 'amount' => 33.12,
190
+ 'currency' => 'USD',
191
+ 'reason' => 'Product Missing'
192
+ )))
193
+ ));
194
+
195
+ echo "\nREQUEST:".PHP_EOL.json_encode(json_decode($refund->toJson())).PHP_EOL;
196
+
197
+ try {
198
+ $response = $transport->refundOrder($refund);
199
+ echo PHP_EOL."Refund Order succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
200
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
201
+ echo PHP_EOL."Refund order not succeeded. Status code was: ".$uae->statusCode." and json body was: "
202
+ .json_encode($uae->jsonResponse).PHP_EOL;
203
+ } catch(Exception $e) {
204
+ echo PHP_EOL."Refund order not succeeded. Exception: ".$e->getMessage().PHP_EOL;
205
+ }
206
+
207
+ try {
208
+ $response = $transport->cancelOrder($order);
209
+ echo PHP_EOL."Cancel order succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
210
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
211
+ echo PHP_EOL."Cancel order not succeeded. Status code was: ".$uae->statusCode." and json body was: "
212
+ .json_encode($uae->jsonResponse).PHP_EOL;
213
+ } catch(Exception $e) {
214
+ echo PHP_EOL."Cancel order not succeeded. Exception: ".$e->getMessage().PHP_EOL;
215
+ }
lib/riskified_php_sdk/sample/run_callback_server.sh ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ # Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this file except in compliance with the License.
7
+ # A copy of the License is located at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0.html
10
+ #
11
+ # or in the "license" file accompanying this file. This file is distributed
12
+ # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ # express or implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #
16
+
17
+ # Launches a standalone server for testing DecisionNotification messages
18
+ # Usage: sample/run_callback_server.sh
19
+
20
+ php -S 0.0.0.0:8000 sample/callback.php
lib/riskified_php_sdk/sample/upload_historical.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ // A simple example of uploading historical orders from the command line.
18
+ // Usage: php upload_historical.php
19
+
20
+ include __DIR__.'/../src/Riskified/autoloader.php';
21
+ use Riskified\Common\Riskified;
22
+ use Riskified\Common\Env;
23
+ use Riskified\Common\Signature;
24
+ use Riskified\OrderWebhook\Model;
25
+ use Riskified\OrderWebhook\Transport;
26
+
27
+ # Replace with the 'shop domain' of your account in Riskified
28
+ $domain = "test.com";
29
+
30
+ # Replace with the 'auth token' listed in the Riskified web app under the 'Settings' Tab
31
+ $authToken = "1388add8a99252fc1a4974de471e73cd";
32
+
33
+ Riskified::init($domain, $authToken, Env::SANDBOX);
34
+
35
+ $first_order = new Model\Order(array(
36
+ 'id' => '1234',
37
+ 'name' => '#1234',
38
+ 'email' => 'great.customer@example.com',
39
+ 'created_at' => '2010-01-10T11:00:00-05:00',
40
+ 'closed_at' => null,
41
+ 'currency' => 'CAD',
42
+ 'updated_at' => '2010-01-10T11:00:00-05:00',
43
+ 'gateway' => 'mypaymentprocessor',
44
+ 'browser_ip' => '124.185.86.55',
45
+ 'total_price' => 113.23,
46
+ 'total_discounts' => 5.0,
47
+ 'cart_token' => '1sdaf23j212',
48
+ 'note' => 'Shipped to my hotel.',
49
+ 'referring_site' => 'google.com'
50
+ ));
51
+
52
+ $second_order = new Model\Order(array(
53
+ 'id' => '1235',
54
+ 'name' => '#1235',
55
+ 'email' => 'great.customer@example.com',
56
+ 'created_at' => '2010-01-10T11:00:00-05:00',
57
+ 'closed_at' => null,
58
+ 'currency' => 'CAD',
59
+ 'updated_at' => '2010-01-10T11:00:00-05:00',
60
+ 'gateway' => 'mypaymentprocessor',
61
+ 'browser_ip' => '124.185.86.55',
62
+ 'total_price' => 113.23,
63
+ 'total_discounts' => 5.0,
64
+ 'cart_token' => '1sdaf23j212',
65
+ 'note' => 'Shipped to my hotel.',
66
+ 'referring_site' => 'google.com'
67
+ ));
68
+
69
+ $orders = array($first_order, $second_order);
70
+
71
+ # Create a curl transport to the Riskified Server
72
+ $transport = new Transport\CurlTransport(new Signature\HttpDataSignature());
73
+ $transport->timeout = 10;
74
+
75
+ try {
76
+ $response = $transport->sendHistoricalOrders($orders);
77
+ echo PHP_EOL."Upload succeeded. Response: ".PHP_EOL.json_encode($response).PHP_EOL;
78
+ } catch(\Riskified\OrderWebhook\Exception\UnsuccessfulActionException $uae) {
79
+ echo PHP_EOL."Upload failed. Status code was: ".$uae->statusCode." and body was: "
80
+ .json_encode($uae->jsonResponse).PHP_EOL;
81
+ } catch(Exception $e) {
82
+ echo PHP_EOL."Upload failed. Exception: ".$e->getMessage().PHP_EOL;
83
+ }
lib/riskified_php_sdk/src/Riskified/Common/Env.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ namespace Riskified\Common;
18
+
19
+
20
+ class Env {
21
+ const PROD = 'prod';
22
+ const STAGING = 'staging';
23
+ const SANDBOX = 'sandbox';
24
+ const DEV = 'development';
25
+ }
26
+
27
+ class Validations {
28
+ const SKIP = 'skip';
29
+ const IGNORE_MISSING = 'ignore_missing';
30
+ const ALL = 'all';
31
+ }
lib/riskified_php_sdk/src/Riskified/Common/Exception/BaseException.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\Common\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ class BaseException extends \Exception {}
lib/riskified_php_sdk/src/Riskified/Common/Riskified.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\Common;
2
+
3
+ /**
4
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License").
7
+ * You may not use this file except in compliance with the License.
8
+ * A copy of the License is located at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0.html
11
+ *
12
+ * or in the "license" file accompanying this file. This file is distributed
13
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14
+ * express or implied. See the License for the specific language governing
15
+ * permissions and limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class Riskified
20
+ * @package Riskified\Common
21
+ */
22
+ class Riskified {
23
+ const VERSION = '1.1.0';
24
+ const API_VERSION = '2';
25
+
26
+ /**
27
+ * @var string Riskified Shop Domain
28
+ */
29
+ public static $domain;
30
+ /**
31
+ * @var string Riskified Auth_Token
32
+ */
33
+ public static $auth_token;
34
+ /**
35
+ * @var string the Riskified environment to which calls are suppose to be sent
36
+ */
37
+ public static $env;
38
+ /**
39
+ * @var string validation mode [SKIP, IGNORE_MISSING, ALL]
40
+ */
41
+ public static $validations;
42
+
43
+
44
+ /**
45
+ * Sets up Riskified credentials. Must be called before any other method can be used.
46
+ * @param $domain string Riskified Shop Domain
47
+ * @param $auth_token string Riskified Auth_Token
48
+ * @param $env string Riskified environment
49
+ * @param $validations string SDK validation mode
50
+ */
51
+ public static function init($domain, $auth_token, $env = Env::SANDBOX, $validations = Validations::ALL) {
52
+ self::$domain = $domain;
53
+ self::$auth_token = $auth_token;
54
+ self::$env = $env;
55
+
56
+ // for backward compatibility (versions 1.0.*)
57
+ if (is_bool($validations))
58
+ $validations = ($validations) ? Validations::SKIP : Validations::ALL;
59
+
60
+ self::$validations = $validations;
61
+
62
+ // suppress timezone warnings:
63
+ date_default_timezone_set(@date_default_timezone_get());
64
+ }
65
+
66
+ public static function getHostByEnv(){
67
+ $env = (self::$env == null) ? Env::SANDBOX : self::$env;
68
+
69
+ switch ($env){
70
+ case Env::SANDBOX:
71
+ return 'sandbox.riskified.com';
72
+ case Env::STAGING:
73
+ return 's.riskified.com';
74
+ case Env::PROD:
75
+ return 'wh.riskified.com';
76
+ case Env::DEV:
77
+ return 'localhost:3000';
78
+ default:
79
+ return 'localhost:3000';
80
+ }
81
+ }
82
+ }
lib/riskified_php_sdk/src/Riskified/Common/Signature/HttpDataSignature.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\Common\Signature;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Riskified;
18
+
19
+ /**
20
+ * Class HttpDataSignature
21
+ * Encapsulate the signature logic for HTTP incoming and outgoing messages using the HMAC SHA256 with the auth_token as
22
+ * the key
23
+ * @package Riskified\Common\Signature
24
+ */
25
+ class HttpDataSignature {
26
+
27
+ const SHOP_DOMAIN_HEADER_NAME = 'X-RISKIFIED-SHOP-DOMAIN';
28
+ const SUBMIT_HEADER_NAME = 'X-RISKIFIED-SUBMIT-NOW';
29
+ const HMAC_HEADER_NAME = 'X-RISKIFIED-HMAC-SHA256';
30
+
31
+ /**
32
+ * Calculates the HMAC SHA256
33
+ * @param $body string Body of POST request to hash
34
+ * @return string Value for HMAC_HEADER_NAME
35
+ */
36
+ public function calc_hmac($body) {
37
+ return hash_hmac('sha256', $body, Riskified::$auth_token);
38
+ }
39
+
40
+ }
lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/AuthorizationException.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\DecisionNotification\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class AuthorizationException
19
+ * Thrown on HMAC mismatch
20
+ * @package Riskified\DecisionNotification\Exception
21
+ */
22
+ class AuthorizationException extends NotificationException{
23
+
24
+ protected $expected_hmac;
25
+ protected $received_hmac;
26
+
27
+ public function __construct($headers, $body, $expected_hmac, $received_hmac) {
28
+ $this->expected_hmac = $expected_hmac;
29
+ $this->received_hmac = $received_hmac;
30
+ parent::__construct($headers, $body);
31
+ }
32
+
33
+ protected function customMessage() {
34
+ return parent::customMessage().
35
+ ', Expected HMAC: '.$this->expected_hmac.
36
+ '. Received HMAC: '.$this->received_hmac;
37
+ }
38
+ }
lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/BadHeaderException.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\DecisionNotification\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class BadHeaderException
19
+ * Thrown on malformed headers
20
+ * @package Riskified\DecisionNotification\Exception
21
+ */
22
+ class BadHeaderException extends NotificationException {
23
+
24
+ protected $header;
25
+
26
+ public function __construct($headers, $body, $header) {
27
+ $this->header = $header;
28
+ parent::__construct($headers, $body);
29
+ }
30
+
31
+ protected function customMessage() {
32
+ return parent::customMessage().
33
+ ', Header: '.$this->header;
34
+ }
35
+ }
lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/BadPostJsonException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\DecisionNotification\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class BadPostJsonException
19
+ * Thrown on bad POST parameters in notification received
20
+ * @package Riskified\DecisionNotification\Exception
21
+ */
22
+ class BadPostJsonException extends NotificationException {}
lib/riskified_php_sdk/src/Riskified/DecisionNotification/Exception/NotificationException.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\DecisionNotification\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class NotificationException
21
+ * Base exception for issues with the Notification Model
22
+ * @package Riskified\DecisionNotification\Exception
23
+ */
24
+ class NotificationException extends BaseException {
25
+
26
+ protected $headers;
27
+ protected $body;
28
+
29
+ public function __construct($headers, $body) {
30
+ $this->headers = $headers;
31
+ $this->body = $body;
32
+ parent::__construct($this->customMessage());
33
+ }
34
+
35
+ protected function headersString() {
36
+ return '[ '.join(', ',$this->headers).' ]';
37
+ }
38
+
39
+ protected function customMessage() {
40
+ return 'Headers: '.$this->headersString().
41
+ ', Body: '.$this->body;
42
+ }
43
+
44
+
45
+ }
lib/riskified_php_sdk/src/Riskified/DecisionNotification/Model/Notification.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\DecisionNotification\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\DecisionNotification\Exception;
18
+
19
+ /**
20
+ * Class Notification
21
+ * Parses and validates Decision Notification callbacks from Riskified
22
+ * @package Riskified\DecisionNotification\Model
23
+ */
24
+ class Notification {
25
+
26
+ /**
27
+ * @var string Order ID
28
+ */
29
+ public $id;
30
+ /**
31
+ * @var string Status of Order
32
+ */
33
+ public $status;
34
+ /**
35
+ * @var string Description of Decision
36
+ */
37
+ public $description;
38
+
39
+ protected $signature;
40
+ protected $headers;
41
+ protected $body;
42
+
43
+ /**
44
+ * Inits and validates the request.
45
+ * @param $signature Signature An instance of a Signature class that handles authentication
46
+ * @param $headers array Associative array of HTTP headers
47
+ * @param $body string The raw body of the Request
48
+ * @throws NotificationException on issues with the request
49
+ */
50
+ public function __construct($signature, $headers, $body) {
51
+ $this->signature = $signature;
52
+ $this->headers = $headers;
53
+ $this->body = $body;
54
+
55
+ $this->test_authorization();
56
+ $this->parse_body();
57
+ }
58
+
59
+ /**
60
+ * assets that the request authentication is valid
61
+ * @throws \Riskified\DecisionNotification\Exception\AuthorizationException on HMAC mismatch
62
+ */
63
+ protected function test_authorization() {
64
+ $signature = $this->signature;
65
+ $remote_hmac = $this->headers[$signature::HMAC_HEADER_NAME];
66
+ $local_hmac = $signature->calc_hmac($this->body);
67
+ if ($remote_hmac != $local_hmac)
68
+ throw new Exception\AuthorizationException($this->headers, $this->body, $local_hmac, $remote_hmac);
69
+ }
70
+
71
+ /**
72
+ * extracts parameters from HTTP POST body
73
+ * @throws \Riskified\DecisionNotification\Exception\BadPostJsonException on bad or missing parameters
74
+ */
75
+ protected function parse_body() {
76
+ $body = json_decode($this->body);
77
+ if (!array_key_exists('order', $body))
78
+ throw new Exception\BadPostJsonException($this->headers, $this->body);
79
+
80
+ $order = $body->{'order'};
81
+ if (!array_key_exists('id', $order) || !array_key_exists('status', $order))
82
+ throw new Exception\BadPostJsonException($this->headers, $this->body);
83
+
84
+ foreach($order as $key => $value)
85
+ $this->$key = $value;
86
+ }
87
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/ClassMismatchPropertyException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class ClassMismatchPropertyException
19
+ * thrown when wrong object assigned to field
20
+ * @package Riskified\OrderWebhook\Exception
21
+ */
22
+ class ClassMismatchPropertyException extends PropertyException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/CurlException.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class CurlException
21
+ * On all cURL errors, including HTTP 500 Bad Auth
22
+ * @package Riskified\OrderWebhook\Exception
23
+ */
24
+ class CurlException extends BaseException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/FormatMismatchPropertyException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class FormatMismatchPropertyException
19
+ * thrown when property value does not match the format regex
20
+ * @package Riskified\OrderWebhook\Exception
21
+ */
22
+ class FormatMismatchPropertyException extends PropertyException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/InvalidPropertyException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class InvalidPropertyException
19
+ * thrown when attempting to set a non-existing property
20
+ * @package Riskified\OrderWebhook\Exception
21
+ */
22
+ class InvalidPropertyException extends PropertyException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MalformedJsonException.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class MalformedJsonException
21
+ * thrown on JSON response parsing issues
22
+ * @package Riskified\OrderWebhook\Exception
23
+ */
24
+ class MalformedJsonException extends BaseException {
25
+
26
+ protected $body;
27
+ protected $status;
28
+
29
+ public function __construct($body, $status) {
30
+ $this->body = $body;
31
+ $this->status = $status;
32
+ parent::__construct($this->customMessage());
33
+ }
34
+
35
+ protected function customMessage() {
36
+ return 'Status Code: '.$this->status.
37
+ ', Body: '.$this->body;
38
+ }
39
+
40
+
41
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MissingPropertyException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class MissingPropertyException
19
+ * thrown when a non-optional property is missing
20
+ * @package Riskified\OrderWebhook\Exception
21
+ */
22
+ class MissingPropertyException extends PropertyException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/MultiplePropertiesException.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class MultiplePropertiesException
21
+ * thrown at the end of an unsuccessful validation, holds a collection of $exceptions encountered
22
+ * @package Riskified\OrderWebhook\Exception
23
+ */
24
+ class MultiplePropertiesException extends BaseException {
25
+
26
+ public $exceptions;
27
+
28
+ public function __construct($exceptions) {
29
+ $this->exceptions = $exceptions;
30
+ parent::__construct($this->customMessage());
31
+ }
32
+
33
+ public function customMessage() {
34
+ $sep = PHP_EOL.' ';
35
+ return $this->count_string().$sep.join($sep, $this->exceptions).PHP_EOL;
36
+ }
37
+
38
+ protected function count_string() {
39
+ return 'Exception count: '.count($this->exceptions);
40
+ }
41
+
42
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/PropertyException.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class PropertyException
21
+ * Base Exception for all OrderWebhook issues
22
+ * @package Riskified\OrderWebhook\Exception
23
+ */
24
+ class PropertyException extends BaseException {
25
+
26
+ protected $className;
27
+ protected $propertyName;
28
+ protected $value;
29
+ protected $types;
30
+
31
+ /**
32
+ * @param string $className of the property
33
+ * @param string $propertyName
34
+ * @param array $types constrains
35
+ * @param mixed $value of the property
36
+ */
37
+ public function __construct($className, $propertyName, $types = null, $value = null) {
38
+ $this->className = $className;
39
+ $this->propertyName = $propertyName;
40
+ $this->value = $value;
41
+ $this->types = $types;
42
+ parent::__construct($this->customMessage());
43
+ }
44
+
45
+ public function __toString() {
46
+ return get_class($this).': '.$this->customMessage();
47
+ }
48
+
49
+ protected function propertyName() {
50
+ return $this->className.'->'.$this->propertyName;
51
+ }
52
+
53
+ protected function propertyValue() {
54
+ if($this->value) {
55
+ return $this->value;
56
+ }
57
+ return '';
58
+ }
59
+
60
+ protected function propertyTypes() {
61
+ if($this->types) {
62
+ return join(', ',$this->types);
63
+ }
64
+ return '';
65
+ }
66
+
67
+ protected function customMessage() {
68
+ return 'Property Name: '.$this->propertyName().
69
+ ', Property Value: '.print_r($this->propertyValue(), true).
70
+ ', Property Type: '.$this->propertyTypes();
71
+ }
72
+
73
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/TypeMismatchPropertyException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class TypeMismatchPropertyException
19
+ * thrown for a value of the wrong type
20
+ * @package Riskified\OrderWebhook\Exception
21
+ */
22
+ class TypeMismatchPropertyException extends PropertyException {}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Exception/UnsuccessfulActionException.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Exception;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Exception\BaseException;
18
+
19
+ /**
20
+ * Class FailedTransmissionException
21
+ * On all unsuccessful transmissions, all HTTP responses with code other than 200 OK
22
+ * @package Riskified\OrderWebhook\Exception
23
+ */
24
+ class UnsuccessfulActionException extends BaseException {
25
+ protected $jsonResponse;
26
+ protected $statusCode;
27
+
28
+ public function __construct($body, $status) {
29
+ $this->jsonResponse = $body;
30
+ $this->statusCode = $status;
31
+ parent::__construct($this->customMessage());
32
+ }
33
+
34
+ protected function customMessage() {
35
+ return 'Http Status Code: '.$this->statusCode.
36
+ ', Error was: '.$this->jsonResponse;
37
+ }
38
+
39
+ function __get($name)
40
+ {
41
+ return isset($this->$name) ? $this->$name : null;
42
+ }
43
+
44
+
45
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/AbstractModel.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\OrderWebhook\Exception;
18
+
19
+ /**
20
+ * Class AbstractModel
21
+ * Abstract superclass for all data models that performs data validation on properties
22
+ * @package Riskified
23
+ */
24
+ abstract class AbstractModel {
25
+
26
+ /**
27
+ * @internal describes allowed fields and their associated validation requirements
28
+ */
29
+ protected $_fields = array();
30
+
31
+ /**
32
+ * Contains all the model properties and their associated values (used by __set and __get)
33
+ * @var array
34
+ */
35
+ protected $_propertyBag = array();
36
+
37
+ /**
38
+ * Ignores missing keys during validation when set to False
39
+ * @var boolean
40
+ */
41
+ protected $_enforce_required_keys = true;
42
+
43
+ /**
44
+ * Initialize a new model, optionally passing an array of properties
45
+ * @param array $props List of Key => Value pairs for setting model properties
46
+ * @throws \Exception If $props contain an invalid Key
47
+ */
48
+ public function __construct($props = array()) {
49
+ foreach ($props as $key => $value) {
50
+ if (!array_key_exists($key, $this->_fields))
51
+ throw new Exception\InvalidPropertyException($this, $key);
52
+ $this->{$key} = $value;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Magic method to enforce defined fields
58
+ * @param string $key Property to set
59
+ * @param string $value New value of property to set
60
+ * @throws \Exception If $key is invalid
61
+ */
62
+ public function __set($key, $value) {
63
+ if (array_key_exists($key, $this->_fields)) {
64
+ $this->_propertyBag[$key] = $value;
65
+ } else {
66
+ throw new Exception\InvalidPropertyException($this, $key);
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Magic method acting as GETTER method for the defined fields
72
+ * @param string $key Property to get
73
+ * @return mixed Value of the property
74
+ * @throws Exception\InvalidPropertyException If $key is invalid
75
+ */
76
+ public function __get($key) {
77
+ if (array_key_exists($key, $this->_fields)) {
78
+ return isset($this->_propertyBag[$key]) ? $this->_propertyBag[$key] : null;
79
+ } else {
80
+ throw new Exception\InvalidPropertyException($this, $key);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Get the short name of the model, ie. without the namespace prefix
86
+ * @return string Short name of the model
87
+ */
88
+ public function __toString() {
89
+ $parts = explode('\\',get_class($this));
90
+ return end($parts);
91
+ }
92
+
93
+ /**
94
+ * Serialize the model to JSON
95
+ * @return string JSON string representation of the model
96
+ */
97
+ public function toJson() {
98
+ return json_encode($this->to_array());
99
+ }
100
+
101
+ /**
102
+ * Serialize the model to XML
103
+ * @return string XML string representation of the model
104
+ */
105
+ public function toXml() {
106
+ $xml_order_info = new \SimpleXMLElement('<?xml version="1.0"?><order></order>');
107
+ $this->array_to_xml($this->to_array(), $xml_order_info);
108
+ return $xml_order_info->asXML();
109
+ }
110
+
111
+ /**
112
+ * Validate all fields and nested objects for this object
113
+ * @param $enforce_required_keys boolean if FALSE then skip validation of missing fields, only report format exceptions
114
+ * @return bool True if object hierarchy is valid
115
+ * @throws \Riskified\OrderWebhook\Exception\MultiplePropertiesException on any or multiple issues
116
+ */
117
+ public function validate($enforce_required_keys=true) {
118
+ $exceptions = $this->validation_exceptions($enforce_required_keys);
119
+ if ($exceptions)
120
+ throw new Exception\MultiplePropertiesException($exceptions);
121
+ return true;
122
+ }
123
+
124
+ /**
125
+ * Validate all fields and nested objects for this object
126
+ * @param $enforce_required_keys boolean if FALSE then skip validation of missing fields, only report format exceptions
127
+ * @return array All property validation issues or empty array if no issues found
128
+ */
129
+ protected function validation_exceptions($enforce_required_keys=true) {
130
+ $this->_enforce_required_keys = $enforce_required_keys;
131
+ $exceptions = array();
132
+ foreach ($this->_fields as $propertyName => $constraints) {
133
+ $types = explode(' ', $constraints);
134
+ if (is_null($this->$propertyName)) {
135
+ if ($this->_enforce_required_keys && end($types) != 'optional') {
136
+ $exceptions[] = new Exception\MissingPropertyException($this, $propertyName, $types);
137
+ }
138
+ } else {
139
+ $exceptions = array_merge($exceptions, $this->validate_key($propertyName, $types, $this->$propertyName));
140
+ }
141
+ }
142
+ return array_filter($exceptions);
143
+ }
144
+
145
+ /**
146
+ * validate a specific key
147
+ * @param $key string key name
148
+ * @param $types array constraints
149
+ * @param $value mixed value to validate
150
+ * @return array validation issues found
151
+ */
152
+ private function validate_key($key, $types, $value) {
153
+ $type = $types[0];
154
+ $exception = array(new Exception\TypeMismatchPropertyException($this, $key, $types, $value));
155
+ switch ($type) {
156
+ case 'string':
157
+ if (!is_string($value))
158
+ return $exception;
159
+ if (count($types) > 1 && $types[1][0] == '/' && !preg_match($types[1], $value))
160
+ return array(new Exception\FormatMismatchPropertyException($this, $key, $types, $value));
161
+ break;
162
+ case 'number':
163
+ if (!preg_match('/^[0-9]+$/', $value))
164
+ return $exception;
165
+ break;
166
+ case 'float':
167
+ if (!is_numeric($value))
168
+ return $exception;
169
+ break;
170
+ case 'boolean':
171
+ if (!is_bool($value))
172
+ return $exception;
173
+ break;
174
+ case 'date':
175
+ if (!$this->is_date($value))
176
+ return $exception;
177
+ break;
178
+ case 'object':
179
+ return $this->validate_object($key, $types, $value);
180
+ break;
181
+ case 'array':
182
+ return $this->validate_array($key, $types, $value);
183
+ break;
184
+ }
185
+ return array();
186
+ }
187
+
188
+ /**
189
+ * validate a nested object
190
+ * @param $key string key name of object
191
+ * @param $types array constraints
192
+ * @param $object object to validate
193
+ * @return array All validation issues or null if no issues found
194
+ */
195
+ private function validate_object($key, $types, $object) {
196
+ if (!is_object($object))
197
+ return array(new Exception\TypeMismatchPropertyException($this, $key, $types, $object));
198
+
199
+ $parts = explode('\\', get_class($object));
200
+ $class = '\\'.end($parts);
201
+
202
+ if (count($types) > 1 && $types[1][0] == '\\' && $class != $types[1]) {
203
+ return array(new Exception\ClassMismatchPropertyException($this, $key, $types, $object));
204
+ }
205
+
206
+ return $object->validation_exceptions($this->_enforce_required_keys);
207
+ }
208
+
209
+ /**
210
+ * validate array of values of a simple type
211
+ * @param $key string key name
212
+ * @param $types string constraints
213
+ * @param $array array elements to validate
214
+ * @return array validations issues or null if no issues found
215
+ */
216
+ private function validate_array($key, $types, $array) {
217
+
218
+ $childTypes = array_slice($types,1); // remove the 'array' and validate each element by defined type+regex that come after
219
+ if (is_array($array)) {
220
+ $exceptions = array();
221
+ foreach ($array as $element) {
222
+ $exceptions = array_merge($exceptions, $this->validate_key($key, $childTypes, $element));
223
+ }
224
+ return array_filter($exceptions);
225
+ }
226
+ return $this->validate_key($key, $childTypes, $array);
227
+ }
228
+
229
+ /**
230
+ * Test if string is a valid date
231
+ * @param string $date String to test
232
+ * @return boolean True if $date is a valid date
233
+ */
234
+ private function is_date($date) {
235
+ return (strtotime($date));
236
+ }
237
+
238
+ /**
239
+ * Get all fields for this model
240
+ * @return array List of all fields
241
+ */
242
+ private function to_array() {
243
+ return $this->process_array($this->_propertyBag);
244
+ }
245
+
246
+ /**
247
+ * Recursively convert models to arrays
248
+ * @param array $array List of fields to convert from models to arrays
249
+ * @return array Nested array
250
+ */
251
+ private function process_array($array) {
252
+ unset($array['_fields']);
253
+ foreach($array as $key => $value) {
254
+ if (is_null($value))
255
+ unset($array[$key]);
256
+ if (is_object($value))
257
+ $array[$key] = $value->to_array();
258
+ if (is_array($value))
259
+ $array[$key] = $this->process_array($value);
260
+ }
261
+ return $array;
262
+ }
263
+
264
+ /**
265
+ * Helper method that converts a nested array to XML
266
+ * @param array $order Nested array to convert
267
+ * @param \SimpleXMLElement $xml_order_info Reference to XML object being constructed
268
+ */
269
+ private function array_to_xml($order, &$xml_order_info) {
270
+ foreach ($order as $key => $value) {
271
+ if (is_array($value)) {
272
+ if (!is_numeric($key)){
273
+ $subnode = $xml_order_info->addChild($key);
274
+ $this->array_to_xml($value, $subnode);
275
+ } else{
276
+ $subnode = $xml_order_info->addChild('item$key');
277
+ $this->array_to_xml($value, $subnode);
278
+ }
279
+ } else {
280
+ $xml_order_info->addChild($key, htmlspecialchars($value));
281
+ }
282
+ }
283
+ }
284
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Address.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Address
19
+ * data model of shipping/billing address
20
+ * @package Riskified
21
+ */
22
+ class Address extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'first_name' => 'string',
26
+ 'last_name' => 'string',
27
+ 'city' => 'string',
28
+ 'phone' => 'string',
29
+ 'country' => 'string',
30
+ 'country_code' => 'string /^[A-Z]{2}$/i',
31
+
32
+ 'name' => 'string optional',
33
+ 'company' => 'string optional',
34
+ 'address1' => 'string optional',
35
+ 'address2' => 'string optional',
36
+ 'province' => 'string optional',
37
+ 'province_code' => 'string /^[A-Z]{2}$/i optional',
38
+ 'zip' => 'string optional',
39
+ 'latitude' => 'float optional',
40
+ 'longitude' => 'float optional',
41
+ );
42
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Attribute.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Attribute
19
+ * data model of generic key-value attribute
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class Attribute extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'name' => 'string',
26
+ 'value' => 'string'
27
+ );
28
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/ClientDetails.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class ClientDetails
19
+ * data model of client details of customer placing order
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class ClientDetails extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'accept_language' => 'string',
26
+ 'browser_ip' => 'string /^(:?[0-9a-f]{0,5}[:\.])+[0-9a-f]{0,4}$/i',
27
+ 'user_agent' => 'string',
28
+
29
+ 'session_hash' => 'string optional'
30
+ );
31
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Customer.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Customer
19
+ * data model of customer in order
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class Customer extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'email' => 'string /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i',
26
+ 'first_name' => 'string',
27
+ 'last_name' => 'string',
28
+
29
+ 'created_at' => 'date optional',
30
+ 'updated_at' => 'date optional',
31
+ 'id' => 'string optional',
32
+ 'note' => 'string optional',
33
+ 'orders_count' => 'number optional',
34
+ 'verified_email' => 'boolean optional',
35
+ 'accepts_marketing' => 'boolean optional',
36
+ 'last_order_id' => 'string optional',
37
+ 'last_order_name' => 'string optional',
38
+ 'state' => 'string optional',
39
+ 'total_spent' => 'float optional',
40
+ 'tags' => 'string optional',
41
+ 'default_address' => 'object \Address optional'
42
+ );
43
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/DiscountCode.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class DiscountCode
19
+ * data model of discounts in order
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class DiscountCode extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'code' => 'string',
26
+ 'amount' => 'float'
27
+ );
28
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Fulfillment.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Fulfillment
19
+ * data model of fulfillment
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class Fulfillment extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'created_at' => 'date',
26
+ 'updated_at' => 'date',
27
+ 'id' => 'string',
28
+ 'order_id' => 'string',
29
+ 'service' => 'string',
30
+ 'status' => 'string',
31
+
32
+ 'tracking_company' => 'string optional',
33
+ 'tracking_number' => 'string optional',
34
+ 'tracking_url' => 'string optional',
35
+ 'line_items' => 'array object \LineItem optional'
36
+ );
37
+ }
38
+
39
+ // "receipt":{"gift_cards":[{"id":732301,"line_item_id":372051657,"masked_code":"\u00b7\u00b7\u00b7\u00b7 \u00b7\u00b7\u00b7\u00b7 \u00b7\u00b7\u00b7\u00b7 gcae"}]}
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/LineItem.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class LineItem
19
+ * data model of line items purchased
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class LineItem extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'price' => 'float',
26
+ 'quantity' => 'number',
27
+ 'title' => 'string',
28
+
29
+ 'sku' => 'string optional',
30
+ 'product_id' => 'string optional',
31
+ 'fulfillment_service' => 'string optional',
32
+ 'fulfillment_status' => 'string optional',
33
+ 'grams' => 'float optional',
34
+ 'id' => 'string optional',
35
+ 'variant_id' => 'string optional',
36
+ 'variant_title' => 'string optional',
37
+ 'variant_inventory_management' => 'string optional',
38
+ 'vendor' => 'string optional',
39
+ 'name' => 'string optional',
40
+ 'requires_shipping' => 'boolean optional',
41
+ 'taxable' => 'boolean optional',
42
+ 'product_exists' => 'boolean optional',
43
+ 'properties' =>'array object \Attribute optional',
44
+ 'tax_lines' => 'array object \TaxLine optional',
45
+ 'event_sub_category_name' => 'string optional',
46
+ 'event_name' => 'string optional',
47
+ 'event_section_name' => 'string optional',
48
+ 'event_date' => 'date optional'
49
+ );
50
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Order.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Order
19
+ * main data model, includes nested models
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class Order extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'id' => 'string',
26
+ 'email' => 'string /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i',
27
+ 'created_at' => 'date',
28
+ 'updated_at' => 'date',
29
+ 'currency' => 'string /^[A-Z]{3}$/i',
30
+ 'gateway' => 'string',
31
+ 'total_price' => 'float',
32
+ 'browser_ip' => 'string /^(:?[0-9a-f]{0,5}[:\.])+[0-9a-f]{0,4}$/i',
33
+
34
+ 'customer' => 'object \Customer',
35
+ 'line_items' => 'array object \LineItem',
36
+
37
+ 'name' => 'string optional',
38
+ 'additional_emails' => 'array string /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i optional',
39
+ 'note' => 'string optional',
40
+ 'number' => 'number optional',
41
+ 'order_number' => 'number optional',
42
+ 'cancel_reason' => 'string optional',
43
+ 'cancelled_at' => 'date optional',
44
+ 'closed_at' => 'date optional',
45
+ 'cart_token' => 'string optional',
46
+ 'checkout_token' => 'string optional',
47
+ 'token' => 'string optional',
48
+ 'referring_site' => 'string optional',
49
+ 'confirmed' => 'boolean optional',
50
+ 'buyer_accepts_marketing' => 'boolean optional',
51
+ 'financial_status' => 'string optional',
52
+ 'fulfillment_status' => 'string optional',
53
+ 'landing_site' => 'string optional',
54
+ 'landing_site_ref' => 'string optional',
55
+ 'location_id' => 'string optional',
56
+ 'source' => 'string optional',
57
+ 'source_identifier' => 'string optional',
58
+ 'source_name' => 'string optional',
59
+ 'source_url' => 'string optional',
60
+ 'subtotal_price' => 'float optional',
61
+ 'taxes_included' => 'boolean optional',
62
+ 'total_discounts' => 'float optional',
63
+ 'total_line_items_price' => 'float optional',
64
+ 'total_price_usd' => 'float optional',
65
+ 'total_tax' => 'float optional',
66
+ 'total_weight' => 'float optional',
67
+ 'user_id' => 'string optional',
68
+ 'processing_method' => 'string optional',
69
+ 'checkout_id' => 'string optional',
70
+ 'tags' => 'string optional',
71
+
72
+ 'shipping_address' => 'object \Address optional',
73
+ 'billing_address' => 'object \Address optional',
74
+ 'payment_details' => 'object \PaymentDetails optional',
75
+ 'client_details' => 'object \ClientDetails optional',
76
+ 'discount_codes' => 'array object \DiscountCode optional',
77
+ 'shipping_lines' => 'array object \ShippingLine optional',
78
+ 'note_attributes' => 'array object \Attribute optional',
79
+ 'tax_lines' => 'array object \TaxLine optional'
80
+ );
81
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/OrderCancellation.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class OrderCancellation
19
+ * main data model for cancellation event
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class OrderCancellation extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'id' => 'string',
26
+ 'cancelled_at' => 'date',
27
+ 'cancel_reason' => 'string'
28
+ );
29
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/PaymentDetails.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class PaymentDetails
19
+ * data model of payment (credit card) details
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class PaymentDetails extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'credit_card_bin' => 'string',
26
+ 'avs_result_code' => 'string /^.+$/i',
27
+ 'cvv_result_code' => 'string /^.+$/i',
28
+ 'credit_card_number' => 'string',
29
+ 'credit_card_company' => 'string',
30
+
31
+ 'payer_email' => 'string optional',
32
+ 'payer_status' => 'string optional',
33
+ 'payer_address_status' => 'string optional',
34
+ 'protection_eligibility' => 'string optional',
35
+ 'payment_status' => 'string optional',
36
+ 'pending_reason' => 'string optional',
37
+ 'authorization_id' => 'string optional'
38
+ );
39
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/Refund.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Refund
19
+ * data model of an exisiting order's refund details
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class Refund extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'id' => 'string',
26
+ 'refunds' => 'array object \RefundDetails'
27
+ );
28
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/RefundDetails.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class Refund
19
+ * data model of an exisiting order's refund details
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class RefundDetails extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'refund_id' => 'string',
26
+ 'amount' => 'double',
27
+ 'currency' => 'string /^[A-Z]{3}$/i',
28
+
29
+ 'refunded_at' => 'date optional',
30
+ 'reason' => 'string optional'
31
+ );
32
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/ShippingLine.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class ShippingLine
19
+ * data model of shipping line costs
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class ShippingLine extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'price' => 'float',
26
+ 'title' => 'string',
27
+
28
+ 'code' => 'string optional',
29
+ 'source' => 'string optional',
30
+ 'tax_lines' => 'array object \TaxLine optional'
31
+ );
32
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Model/TaxLine.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Model;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * Class TaxLine
19
+ * data model of tax line in order
20
+ * @package Riskified\OrderWebhook\Model
21
+ */
22
+ class TaxLine extends AbstractModel {
23
+
24
+ protected $_fields = array(
25
+ 'price' => 'float',
26
+ 'rate' => 'float',
27
+ 'title' => 'string'
28
+ );
29
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Transport/AbstractTransport.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Transport;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\Common\Env;
18
+ use Riskified\Common\Riskified;
19
+ use Riskified\Common\Validations;
20
+
21
+ /**
22
+ * Class AbstractTransport
23
+ * A base class for Transports for sending order data to Riskified
24
+ * Orders will be created if the id was never used before, and updated if already created
25
+ * Submission of orders is done by similarly to creation with an addition of a header
26
+ * @package Riskified
27
+ */
28
+ abstract class AbstractTransport {
29
+
30
+ /**
31
+ * @var boolean set false to use HTTP instead
32
+ */
33
+ public $use_https = true;
34
+ protected $url;
35
+ protected $signature;
36
+ protected $user_agent;
37
+
38
+ /**
39
+ * submit an order as json
40
+ * @param $json object Order to send
41
+ * @param $endpoint String API endpoint to send request
42
+ */
43
+ abstract protected function send_json_request($json, $endpoint);
44
+
45
+ /**
46
+ * set up transport
47
+ * @param $signature object Signature object for authentication handling
48
+ * @param $url string Riskified endpoint (optional)
49
+ */
50
+ public function __construct($signature, $url = null) {
51
+ $this->signature = $signature;
52
+ $this->url = ($url == null) ? Riskified::getHostByEnv() : $url;
53
+ $this->user_agent = 'riskified_php_sdk/' . Riskified::VERSION;
54
+ $this->use_https = Riskified::$env != Env::DEV;
55
+ }
56
+
57
+ /**
58
+ * Submit an Order to Riskified for review
59
+ * @param $order object Order to submit
60
+ * @return object Response object
61
+ * @throws \Riskified\Common\Exception\BaseException on any issue
62
+ */
63
+ public function submitOrder($order) {
64
+ return $this->send_order($order, 'submit', true);
65
+ }
66
+
67
+ /**
68
+ * Send an Order to Riskified, will be reviewed based on current plan
69
+ * @param $order object Order to send
70
+ * @return object Response object
71
+ * @throws \Riskified\Common\Exception\BaseException on any issue
72
+ */
73
+ public function createOrder($order) {
74
+ return $this->send_order($order, 'create', true);
75
+ }
76
+
77
+ /**
78
+ * Update an existing order
79
+ * @param $order object Order with updated fields
80
+ * @return object Response object
81
+ * @throws \Riskified\Common\Exception\BaseException on any issue
82
+ */
83
+ public function updateOrder($order) {
84
+ return $this->send_order($order, 'update', false);
85
+ }
86
+
87
+ /**
88
+ * Cancels an existing order
89
+ * @param $order object Order with id, cancelled_at, cancel_reason fields
90
+ * @return object Response object
91
+ * @throws \Riskified\Common\Exception\BaseException on any issue
92
+ */
93
+ public function cancelOrder($order) {
94
+ return $this->send_order($order, 'cancel', false);
95
+ }
96
+
97
+ /**
98
+ * Partially refunds an existing order
99
+ * @param $order object Order with id and refunds object
100
+ * @return object Response object
101
+ * @throws \Riskified\Common\Exception\BaseException on any issue
102
+ */
103
+ public function refundOrder($order) {
104
+ return $this->send_order($order, 'refund', false);
105
+ }
106
+
107
+ public function sendHistoricalOrders($orders) {
108
+ $joined = join(',',array_map(function($order) { return $order->toJson(); }, $orders));
109
+ $json = '{"orders":['.$joined.']}';
110
+ return $this->send_json_request($json, 'historical');
111
+ }
112
+
113
+ protected function send_order($order, $endpoint, $enforce_required_keys) {
114
+ if ($this->validate($order, $enforce_required_keys)) {
115
+ $json = '{"order":' . $order->toJson() . '}';
116
+ return $this->send_json_request($json, $endpoint);
117
+ }
118
+ return null;
119
+ }
120
+
121
+ protected function validate($order, $enforce_required_keys=true) {
122
+ if (Riskified::$validations == Validations::SKIP)
123
+ return true;
124
+ return $order->validate($enforce_required_keys && Riskified::$validations == Validations::ALL);
125
+ }
126
+
127
+ /**
128
+ * path prefix to the Riskified endpoint
129
+ * @return string
130
+ */
131
+ protected function endpoint_prefix() {
132
+ $protocol = ($this->use_https) ? 'https' : 'http';
133
+ return "$protocol://$this->url/api/";
134
+ }
135
+
136
+ /**
137
+ * construct headers for request
138
+ * @param $data_string string body of request
139
+ * @return array headers
140
+ */
141
+ protected function headers($data_string) {
142
+ $signature = $this->signature;
143
+ return array(
144
+ 'Content-Type: application/json',
145
+ 'Content-Length: '.strlen($data_string),
146
+ $signature::SHOP_DOMAIN_HEADER_NAME.':'.Riskified::$domain,
147
+ $signature::HMAC_HEADER_NAME.':'.$this->signature->calc_hmac($data_string),
148
+ 'Accept: application/vnd.riskified.com; version='.Riskified::API_VERSION
149
+ );
150
+ }
151
+ }
lib/riskified_php_sdk/src/Riskified/OrderWebhook/Transport/CurlTransport.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace Riskified\OrderWebhook\Transport;
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ use Riskified\OrderWebhook\Exception;
18
+ /**
19
+ * Class CurlTransport
20
+ * @package Riskified
21
+ */
22
+ class CurlTransport extends AbstractTransport {
23
+
24
+ /**
25
+ * @var int
26
+ */
27
+ public $timeout = 10;
28
+ public $dns_cache = true;
29
+
30
+ /**
31
+ * @param $order object Order to send
32
+ * @param $endpoint String API endpoint to send request
33
+ * @return mixed
34
+ * @throws \Riskified\OrderWebhook\Exception\UnsuccessfulActionException
35
+ * @throws \Riskified\OrderWebhook\Exception\CurlException
36
+ */
37
+ protected function send_json_request($json, $endpoint) {
38
+ $ch = curl_init($this->endpoint_prefix().$endpoint);
39
+ $curl_options = array(
40
+ CURLOPT_POSTFIELDS => $json,
41
+ CURLOPT_CUSTOMREQUEST => 'POST',
42
+ CURLOPT_RETURNTRANSFER => true,
43
+ CURLOPT_HTTPHEADER => $this->headers($json),
44
+ CURLOPT_FOLLOWLOCATION => true,
45
+ CURLOPT_USERAGENT => $this->user_agent,
46
+ CURLOPT_TIMEOUT => $this->timeout,
47
+ CURLOPT_DNS_USE_GLOBAL_CACHE => $this->dns_cache,
48
+ CURLOPT_FAILONERROR => false
49
+ );
50
+ curl_setopt_array($ch, $curl_options);
51
+
52
+
53
+ $body = curl_exec($ch);
54
+ if (curl_errno($ch)) {
55
+ throw new Exception\CurlException(curl_error($ch), curl_errno($ch));
56
+ }
57
+
58
+ $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
59
+ curl_close($ch);
60
+
61
+ return $this->json_response($body, $status);
62
+ }
63
+
64
+ /**
65
+ * @param $body
66
+ * @param $status
67
+ * @return mixed
68
+ * @throws \Riskified\OrderWebhook\Exception\MalformedJsonException
69
+ * @throws \Riskified\OrderWebhook\Exception\UnsuccessfulActionException
70
+ */
71
+ private function json_response($body, $status) {
72
+ $response = json_decode($body);
73
+
74
+ if (!$response)
75
+ throw new Exception\MalformedJsonException($body, $status);
76
+ if($status != 200)
77
+ throw new Exception\UnsuccessfulActionException($body, $status);
78
+
79
+ return $response;
80
+ }
81
+ }
lib/riskified_php_sdk/src/Riskified/autoloader.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2013-2014 Riskified.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License").
6
+ * You may not use this file except in compliance with the License.
7
+ * A copy of the License is located at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0.html
10
+ *
11
+ * or in the "license" file accompanying this file. This file is distributed
12
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13
+ * express or implied. See the License for the specific language governing
14
+ * permissions and limitations under the License.
15
+ */
16
+
17
+ function riskifiedAutoload($class) {
18
+ $parts = explode('\\', $class);
19
+ if (array_shift($parts) == 'Riskified') {
20
+ array_unshift($parts, __DIR__);
21
+ $file = join('/',$parts).'.php';
22
+ if (is_file($file))
23
+ require_once $file;
24
+ }
25
+ return true;
26
+ }
27
+
28
+ // Register Riskified autoloader into the SPL autoloading stack (in order to support multiple autoloaders)
29
+ spl_autoload_register('riskifiedAutoload',null,true);
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>riskified_magento</name>
4
+ <version>1.0.5.4</version>
5
+ <stability>stable</stability>
6
+ <license>OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Riskified Magento extension</summary>
10
+ <description>Riskified reviews, approves &amp; guarantees&#xD;
11
+ transactions you would otherwise decline.</description>
12
+ <notes>* validations fix to support shopgate&#xD;
13
+ </notes>
14
+ <authors><author><name>Riskified_Mage</name><user>Riskified_Mage</user><email>support@riskified.com</email></author></authors>
15
+ <date>2014-11-06</date>
16
+ <time>17:16:26</time>
17
+ <contents><target name="magecommunity"><dir name="Riskified"><dir name="Full"><dir><dir name="Helper"><file name="Data.php" hash="1bcd0f37cdce5097054978bcafe02170"/><file name="Debug.php" hash="18335d988a142ee639ea59dbecafa15c"/><file name="Log.php" hash="14125243576ab5b08f40066d24b7241d"/><dir name="Order"><file name="Invoice.php" hash="fd6fcbdedd44551785eddd0e1a482e80"/><file name="Status.php" hash="566aeaed499f41d81d997ca50b932257"/></dir><file name="Order.php" hash="ea5fd37f550cc1923a7bb513d5258a62"/></dir><dir name="Model"><file name="Authorizenet.php" hash="bd42f62d06a036b9da7709d2e40fc8f1"/><file name="Cron.php" hash="187b86ebe9238ff132ed0337f05a8ae9"/><file name="Observer.php" hash="bf609db8bc0b223b04e9bd0d1c726ec2"/><dir name="Resource"><dir name="Retry"><file name="Collection.php" hash="fd62ad4e4cdd8d372751bfa9988cc3a9"/></dir><file name="Retry.php" hash="3be3db7e54bd8bb45e0faffa1941f515"/></dir><file name="Retry.php" hash="89e7344139affa4fe0b9a252a5d1c592"/><dir name="System"><dir name="Config"><dir name="Source"><file name="CaptureCase.php" hash="daafa6f53c65fa6e6e7ffbb067dbbbba"/><file name="Env.php" hash="4d923355b3e56fac95c2a9b3c353ab76"/></dir></dir></dir></dir><dir name="Test"><dir name="Config"><file name="General.php" hash="a5d4950c5655960879e7d75c06977941"/></dir><dir name="Helper"><dir name="General"><dir name="fixtures"><file name="extensionConfigEnabled.yaml" hash="eec8c8d8a1d5de49897b19740cf8e074"/></dir></dir><file name="General.php" hash="607c9711656be48084f6688e114b6bf6"/></dir><dir name="Model"><file name="Environments.php" hash="f3fc028d17c82b9b84b709b932e64eae"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="FullController.php" hash="f80e78a808e99f11a7bc00bd02be3f2e"/></dir><file name="ResponseController.php" hash="4e15f520c0df04e0fdd4a1737b3129d6"/></dir><dir name="etc"><file name="config.xml" hash="3b0152e3ed0c4df5bfb4c80cdb533f7d"/><file name="system.xml" hash="983bd49f77d27ecce3e88266f40f550f"/></dir><dir name="sql"><dir name="riskified_full_setup"><file name="mysql4-install-1.0.1.php" hash="6d29dde79353e8bfefa6ea7bc2ef562a"/><file name="mysql4-install-1.0.2.1.php" hash="822e85326678a320f141a3ae948e4a24"/><file name="mysql4-upgrade-1.0.4-1.0.5.0.php" hash="557115e1a978d9b194b2cd1cfb8b5a95"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Riskified_Full.xml" hash="d684caecdf710e5d0173ca07e5c5d1c0"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="full.xml" hash="8dbb3dd16fcb5821eb07e9b5d978d55c"/></dir><dir name="template"><dir name="full"><file name="jsinit.phtml" hash="1fa1a2c756390efab5d74835c14d743e"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="full.xml" hash="9497753e5c3d2860062c5446c058b4bc"/></dir><dir name="template"><dir name="full"><file name="riskified.phtml" hash="fe4a577c6ef98316d906c36c17f11406"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><dir name="riskified"><file name="logo.jpg" hash="0ac96bf07aa8b8ecb3ff06c2ccbf0827"/></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="riskified_php_sdk"><file name="README.md" hash="f37118baa641e4ef6d670bb1c0298482"/><dir><dir name="sample"><file name="callback.php" hash="e0e206ca3553f2c0922a15a7481cb8f4"/><file name="order_webhook.php" hash="cf8e01be41300977badd171849bf8022"/><file name="run_callback_server.sh" hash="4094bd7d6579f1e5d3a50f8c7b59d5ec"/><file name="upload_historical.php" hash="7ab3a6d71d49067cd612f9ea9b5c4d61"/></dir><dir name="src"><dir name="Riskified"><dir name="Common"><file name="Env.php" hash="84e45f0aa5bd289db005825a8180a10d"/><dir name="Exception"><file name="BaseException.php" hash="6b0c99663a9464b1d94a70647762fbbd"/></dir><file name="Riskified.php" hash="b9ad80ceadfbc1e7eb9aa35dd8686685"/><dir name="Signature"><file name="HttpDataSignature.php" hash="1dd9e2860b72a950129915e31b8098d7"/></dir></dir><dir name="DecisionNotification"><dir name="Exception"><file name="AuthorizationException.php" hash="d0afa3159091dee8dfc2edbf78605e4b"/><file name="BadHeaderException.php" hash="a9ad232eccc5f3fbf2385229b3917fdc"/><file name="BadPostJsonException.php" hash="e9c6c80fc14f61b6f4dc679268cc9a62"/><file name="NotificationException.php" hash="e7471ba97940647607f6d93e04634694"/></dir><dir name="Model"><file name="Notification.php" hash="107f8832c53c361c0b249d9a2524f230"/></dir></dir><dir name="OrderWebhook"><dir name="Exception"><file name="ClassMismatchPropertyException.php" hash="0b61463eecd2b4b237c50efc90ea5651"/><file name="CurlException.php" hash="c98029e1388f37a891f5beb43518267b"/><file name="FormatMismatchPropertyException.php" hash="d7577cc5fe88341118a489c3e153da63"/><file name="InvalidPropertyException.php" hash="331144340d634a5c100ca9c4f85347c8"/><file name="MalformedJsonException.php" hash="168231cdde49266f7f35b8c122a2aa10"/><file name="MissingPropertyException.php" hash="3f905c4999f3d31b2ee798cbd09cb12f"/><file name="MultiplePropertiesException.php" hash="d6d6e681bed74a479ccf271b2a77a73a"/><file name="PropertyException.php" hash="dbe58dcc08acdc52d5619340257ca193"/><file name="TypeMismatchPropertyException.php" hash="df81b3eb45b8979466dd2bafc205b4e8"/><file name="UnsuccessfulActionException.php" hash="a7c0ceb6ad717fe4aadddd737dc229e9"/></dir><dir name="Model"><file name="AbstractModel.php" hash="e29ec55ba50896ea098fdfd088708dbb"/><file name="Address.php" hash="9aa66915feaa94c38c5e06c7e33bd136"/><file name="Attribute.php" hash="621d144b627f5be7850e14e557397270"/><file name="ClientDetails.php" hash="64257d1b717a9bfd1505f7b647aba488"/><file name="Customer.php" hash="907022894f3ed02029ac5eee839d62a6"/><file name="DiscountCode.php" hash="8c6aedd5ca895deb3df6de23e985f505"/><file name="Fulfillment.php" hash="fc008b1b39f2d459637a1b9d32246ab8"/><file name="LineItem.php" hash="06895618140d24fb8d9f0530d7b5d278"/><file name="Order.php" hash="6d1b11d9d5ccaf405bc8fceb01348519"/><file name="OrderCancellation.php" hash="1cf46df75a02e2e28df30b38518ce11c"/><file name="PaymentDetails.php" hash="a0fd3db455eb045241b3fd9b49ab3a18"/><file name="Refund.php" hash="2730565ede65b148da38cee4b3d28c9c"/><file name="RefundDetails.php" hash="cb307e6893fcb68666d0e00ff1fa52b5"/><file name="ShippingLine.php" hash="67df5f3ae5dc14b0751a0ee1824511cc"/><file name="TaxLine.php" hash="f5ebdea62d786c06766609d9d7aa4fc8"/></dir><dir name="Transport"><file name="AbstractTransport.php" hash="f11f1ec189b2940cd89c01dde0ddfe12"/><file name="CurlTransport.php" hash="50f4f69ef329bcc552b546393d8fe86e"/></dir></dir><file name="autoloader.php" hash="67658efe459a30d30e30f7bb52ccdedf"/></dir></dir></dir><file name=".gitignore" hash="73f01e1298c44b6cc3e24a70cad8c56c"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>4.4.0</min><max>6.0.0</max></php></required></dependencies>
20
+ </package>
skin/adminhtml/default/default/images/riskified/logo.jpg ADDED
Binary file