├── .DS_Store ├── .gitignore ├── Duitku.php ├── Duitku ├── .DS_Store ├── Api.php ├── Config.php ├── Pop.php ├── Request.php └── Sanitizer.php ├── README.md ├── composer.json ├── example ├── composer │ ├── Callback-Api.php │ ├── Callback.php │ ├── CreateInvoice-Api.php │ ├── CreateInvoice.html │ ├── CreateInvoice.php │ ├── GetPaymentMethod-Api.php │ ├── GetPaymentMethod.php │ ├── TransactionStatus-Api.php │ ├── TransactionStatus.php │ └── composer.json ├── env │ ├── .env │ ├── Callback-Api.php │ ├── Callback.php │ ├── CreateInvoice-Api.php │ ├── CreateInvoice.html │ ├── CreateInvoice.php │ ├── Duitku.php │ ├── Duitku │ │ ├── Api.php │ │ ├── Config.php │ │ ├── Pop.php │ │ ├── Request.php │ │ └── Sanitizer.php │ ├── GetPaymentMethod-Api.php │ ├── GetPaymentMethod.php │ ├── PhpDotEnv │ │ └── DotEnv.php │ ├── TransactionStatus-Api.php │ └── TransactionStatus.php └── non-composer │ ├── Callback-Api.php │ ├── Callback.php │ ├── CreateInvoice-Api.php │ ├── CreateInvoice.html │ ├── CreateInvoice.php │ ├── Duitku.php │ ├── GetPaymentMethod-Api.php │ ├── GetPaymentMethod.php │ ├── TransactionStatus-Api.php │ ├── TransactionStatus.php │ └── lib │ ├── Api.php │ ├── Config.php │ ├── Pop.php │ ├── Request.php │ └── Sanitizer.php └── tests ├── CallbackApiTest.php ├── CallbackTest.php ├── CreateInvoiceApiTest.php ├── CreateInvoiceTest.php ├── GetPaymentMethodApiTest.php ├── GetPaymentMethodTest.php ├── TransactionStatusApiTest.php ├── TransactionStatusTest.php └── params └── ParamsCallback.json /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duitkupg/duitku-php/983001aefdce35f2d994bfa1e84825169c1b930f/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | composer.lock 3 | vendor/ -------------------------------------------------------------------------------- /Duitku.php: -------------------------------------------------------------------------------- 1 | = 5.6 required'); 8 | } 9 | 10 | // Check PHP Curl & 11 | if (!function_exists('curl_init') || !function_exists('curl_exec')) { 12 | throw new Exception('Duitku::cURL library is required'); 13 | } 14 | 15 | // Json decode capabilities. 16 | if (!function_exists('json_decode')) { 17 | throw new Exception('Duitku::JSON PHP extension is required'); 18 | } 19 | 20 | // Configuration Duitku Config 21 | require_once 'Duitku/Config.php'; 22 | // Duitku Sanitizer Parameter 23 | require_once 'Duitku/Sanitizer.php'; 24 | // Duitku Request Curl 25 | require_once 'Duitku/Request.php'; 26 | // General Duitku-Pop Request 27 | require_once 'Duitku/Pop.php'; 28 | // General Duitku-API Request 29 | require_once 'Duitku/Api.php'; 30 | -------------------------------------------------------------------------------- /Duitku/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duitkupg/duitku-php/983001aefdce35f2d994bfa1e84825169c1b930f/Duitku/.DS_Store -------------------------------------------------------------------------------- /Duitku/Api.php: -------------------------------------------------------------------------------- 1 | $firstName, 43 | * 'lastName' => $lastName, 44 | * 'address' => $alamat, 45 | * 'city' => $city, 46 | * 'postalCode' => $postalCode, 47 | * 'phone' => $phoneNumber, 48 | * 'countryCode' => $countryCode 49 | * ); 50 | * 51 | * $customerDetail = array( 52 | * 'firstName' => $firstName, 53 | * 'lastName' => $lastName, 54 | * 'email' => $email, 55 | * 'phoneNumber' => $phoneNumber, 56 | * 'billingAddress' => $address, 57 | * 'shippingAddress' => $address 58 | * ); 59 | * 60 | * // Item Details 61 | * $item1 = array( 62 | * 'name' => $productDetails, 63 | * 'price' => $paymentAmount, 64 | * 'quantity' => 1 65 | * ); 66 | * 67 | * $itemDetails = array( 68 | * $item1 69 | * ); 70 | * 71 | * $params = array( 72 | * 'paymentAmount' => $paymentAmount, 73 | * 'paymentMethod' => $paymentMethod, 74 | * 'merchantOrderId' => $merchantOrderId, 75 | * 'productDetails' => $productDetails, 76 | * 'additionalParam' => $additionalParam, 77 | * 'merchantUserInfo' => $merchantUserInfo, 78 | * 'customerVaName' => $customerVaName, 79 | * 'email' => $email, 80 | * 'phoneNumber' => $phoneNumber, 81 | * 'itemDetails' => $itemDetails, 82 | * 'customerDetail' => $customerDetail, 83 | * 'callbackUrl' => $callbackUrl, 84 | * 'returnUrl' => $returnUrl, 85 | * 'expiryPeriod' => $expiryPeriod 86 | * ); 87 | * 88 | * try { 89 | * // createInvoice Request 90 | * $responseDuitkuApi = \Duitku\Api::createInvoice($params, $config); 91 | * 92 | * header('Content-Type: application/json'); 93 | * echo $responseDuitkuApi; 94 | * } catch (Exception $e) { 95 | * echo $e->getMessage(); 96 | * } 97 | * 98 | * ``` 99 | * @param array $payload 100 | * @param \Duitku\Config $config 101 | * @return string response duitku API. 102 | * @throws Exception 103 | */ 104 | public static function createInvoice($payload, $config) 105 | { 106 | if ($config->getSanitizedMode()) { 107 | \Duitku\Sanitizer::request($payload); 108 | } 109 | 110 | $timestamp = round(microtime(true) * 1000); 111 | $payload["merchantCode"] = $config->getMerchantCode(); 112 | $payload["signature"] = md5($config->getMerchantCode() . $payload["merchantOrderId"] . $payload["paymentAmount"] . $config->getApiKey()); 113 | 114 | $params = json_encode($payload); 115 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 116 | $url = $config->getApiUrl() . '/webapi/api/merchant/v2/inquiry'; 117 | return self::sendRequest($url, $params, $config, $setLogFunction); 118 | } 119 | 120 | /** 121 | * Cek Transaction Duitku API 122 | * 123 | * Example: 124 | * 125 | * ```php 126 | * 127 | * try { 128 | * $merchantOrderId = "YOUR_ORDER_ID"; 129 | * $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $config); 130 | * 131 | * header('Content-Type: application/json'); 132 | * echo json_encode($transactionList); 133 | * 134 | * if ($transaction->statusCode == "00") { 135 | * // Action Success 136 | * } else if ($transaction->statusCode == "01") { 137 | * // Action Pending 138 | * } else { 139 | * // Action Failed Or Expired 140 | * } 141 | * } 142 | * catch (Exception $e) { 143 | * echo $e->getMessage(); 144 | * } 145 | * ``` 146 | * 147 | * @param string $merchantOrderId 148 | * @param \Duitku\Config $config 149 | * @return string response cek status duitku API. 150 | * @throws Exception 151 | */ 152 | public static function transactionStatus($merchantOrderId, $config) 153 | { 154 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 155 | 156 | $payload = array( 157 | 'merchantCode' => $config->getMerchantCode(), 158 | 'merchantOrderId' => $merchantOrderId, 159 | 'signature' => $signature 160 | ); 161 | 162 | $params = json_encode($payload); 163 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 164 | $url = $config->getApiUrl() . '/webapi/api/merchant/transactionStatus'; 165 | return self::sendRequest($url, $params, $config, $setLogFunction); 166 | } 167 | 168 | /** 169 | * Get List Payment Method Duitku API 170 | * 171 | * Example: 172 | * 173 | * ```php 174 | * 175 | * try { 176 | * $paymentAmount = 10000; 177 | * $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $config); 178 | * 179 | * var_dump(paymentMethodList) 180 | * 181 | * } 182 | * catch (Exception $e) { 183 | * echo $e->getMessage(); 184 | * } 185 | * ``` 186 | * 187 | * @param \Duitku\Config $config 188 | * @return string response cek status duitku API. 189 | * @throws Exception 190 | */ 191 | public static function getPaymentMethod($paymentAmount, $config) 192 | { 193 | $datetime = date('Y-m-d H:i:s'); 194 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 195 | 196 | $payload = array( 197 | 'merchantCode' => $config->getMerchantCode(), 198 | 'amount' => $paymentAmount, 199 | 'datetime' => $datetime, 200 | 'signature' => $signature 201 | ); 202 | 203 | $params = json_encode($payload); 204 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 205 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 206 | return self::sendRequest($url, $params, $config, $setLogFunction); 207 | } 208 | 209 | /** 210 | * Callback Duitku API 211 | * Handle Method HTTP POST => Type x-www-form-urlencoded 212 | * 213 | * Example 214 | * 215 | * try { 216 | * $callback = \Duitku\Api::callback($config); 217 | * 218 | * header('Content-Type: application/json'); 219 | * $notif = json_decode($callback); 220 | * 221 | * if ($notif->resultCode == "00") { 222 | * // Action Success 223 | * } else if ($notif->resultCode == "01") { 224 | * // Action Pending 225 | * } else { 226 | * // Ignore 227 | * } 228 | * 229 | * } catch (Exception $e) { 230 | * http_response_code(400); 231 | * echo $e->getMessage(); 232 | * } 233 | * 234 | * @param \Duitku\Config $config 235 | * @return json response 236 | * @throws Exception 237 | */ 238 | public static function callback($config) 239 | { 240 | $notification = $_POST; 241 | if (empty($notification)) { 242 | throw new \Exception('Access denied'); 243 | } 244 | 245 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 246 | 247 | foreach ($config->callbackParams as $callbackParam) { 248 | if (!array_key_exists($callbackParam, $notification)) { 249 | $notification[$callbackParam] = null; 250 | } 251 | } 252 | 253 | if (!self::isSignatureValid($notification, $config)) { 254 | throw new \Exception('Signature Invalid'); 255 | } 256 | 257 | return json_encode($notification); 258 | } 259 | 260 | /** 261 | * Validation signature callback duitku API 262 | * 263 | */ 264 | private static function isSignatureValid($notification, $config) 265 | { 266 | $signature = $notification['signature']; 267 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 268 | return $signature == $signGenerate; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /Duitku/Config.php: -------------------------------------------------------------------------------- 1 | _apiKey = $apiKey; 22 | $this->_merchantCode = $merchantCode; 23 | $this->_isSandboxMode = $isSandboxMode; 24 | $this->_isSanitizedMode = $isSanitizedMode; 25 | $this->_duitkuLogs = $duitkuLogs; 26 | } 27 | 28 | /** 29 | * Your merchant's api key 30 | * 31 | */ 32 | private $_apiKey; 33 | /** 34 | * Your merchant's merchant code 35 | * 36 | */ 37 | private $_merchantCode; 38 | /** 39 | * false for production 40 | * true for sandbox 41 | * 42 | */ 43 | private $_isSandboxMode; 44 | /** 45 | * Enable request params sanitized mode / default true 46 | * 47 | */ 48 | private $_isSanitizedMode; 49 | /** 50 | * Set it true to enable log file 51 | * 52 | */ 53 | private $_duitkuLogs; 54 | 55 | /** 56 | * Set Callback Parameter 57 | * 58 | */ 59 | public $callbackParams = array( 60 | "merchantCode", 61 | "amount", 62 | "merchantOrderId", 63 | "productDetail", 64 | "additionalParam", 65 | "paymentCode", 66 | "resultCode", 67 | "merchantUserId", 68 | "reference", 69 | "signature", 70 | "spUserHash" 71 | ); 72 | 73 | const SANDBOX_URL = 'https://api-sandbox.duitku.com'; 74 | const PASSPORT_URL = 'https://api-prod.duitku.com'; 75 | 76 | const SANDBOX_API_URL = 'https://sandbox.duitku.com'; 77 | const PASSPORT_API_URL = 'https://passport.duitku.com'; 78 | 79 | /** 80 | * Set apiKey config 81 | * 82 | */ 83 | public function setApiKey($apiKey) 84 | { 85 | $this->_apiKey = $apiKey; 86 | } 87 | 88 | /** 89 | * Get apiKey config 90 | * 91 | */ 92 | public function getApiKey() 93 | { 94 | return $this->_apiKey; 95 | } 96 | 97 | /** 98 | * Set merchantCode config 99 | * 100 | */ 101 | public function setMerchantCode($merchantCode) 102 | { 103 | $this->_merchantCode = $merchantCode; 104 | } 105 | 106 | /** 107 | * Get merchantCode config 108 | * 109 | */ 110 | public function getMerchantCode() 111 | { 112 | return $this->_merchantCode; 113 | } 114 | 115 | /** 116 | * Set sandboxMode config 117 | * 118 | */ 119 | public function setSandboxMode($isSandboxMode) 120 | { 121 | $this->_isSandboxMode = $isSandboxMode; 122 | } 123 | 124 | /** 125 | * Get sandboxMode config 126 | * 127 | */ 128 | public function getSandboxMode() 129 | { 130 | return $this->_isSandboxMode; 131 | } 132 | 133 | /** 134 | * Set sanitizedMode config 135 | * 136 | */ 137 | public function setSanitizedMode($isSanitizedMode) 138 | { 139 | $this->_isSanitizedMode = $isSanitizedMode; 140 | } 141 | 142 | /** 143 | * Get sanitizedMode config 144 | * 145 | */ 146 | public function getSanitizedMode() 147 | { 148 | return $this->_isSanitizedMode; 149 | } 150 | 151 | /** 152 | * Set duitkuLogs config 153 | * 154 | */ 155 | public function setDuitkuLogs($duitkuLogs) 156 | { 157 | $this->_duitkuLogs = $duitkuLogs; 158 | } 159 | 160 | /** 161 | * Get duitkuLogs config 162 | * 163 | */ 164 | public function getDuitkuLogs() 165 | { 166 | return $this->_duitkuLogs; 167 | } 168 | 169 | /** 170 | * Get apiUrl 171 | * 172 | * @return Duitku API URL, depends on $_isSandboxMode 173 | */ 174 | public function getApiUrl() 175 | { 176 | if ($this->getSandboxMode()) { 177 | return self::SANDBOX_API_URL; 178 | } else { 179 | return self::PASSPORT_API_URL; 180 | } 181 | } 182 | 183 | /** 184 | * Get baseUrl 185 | * 186 | * @return Duitku POP URL, depends on $_isSandboxMode 187 | */ 188 | public function getBaseUrl() 189 | { 190 | if ($this->getSandboxMode()) { 191 | return self::SANDBOX_URL; 192 | } else { 193 | return self::PASSPORT_URL; 194 | } 195 | } 196 | 197 | /** 198 | * Generate string log file name 199 | * 200 | * @return string 201 | */ 202 | public function getLogFileName() 203 | { 204 | $logFileName = "duitku_" . date('Ymd') . ".log"; 205 | return $logFileName; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /Duitku/Pop.php: -------------------------------------------------------------------------------- 1 | $firstName, 42 | * 'lastName' => $lastName, 43 | * 'address' => $alamat, 44 | * 'city' => $city, 45 | * 'postalCode' => $postalCode, 46 | * 'phone' => $phoneNumber, 47 | * 'countryCode' => $countryCode 48 | * ); 49 | * 50 | * $customerDetail = array( 51 | * 'firstName' => $firstName, 52 | * 'lastName' => $lastName, 53 | * 'email' => $email, 54 | * 'phoneNumber' => $phoneNumber, 55 | * 'billingAddress' => $address, 56 | * 'shippingAddress' => $address 57 | * ); 58 | * 59 | * // Item Details 60 | * $item1 = array( 61 | * 'name' => $productDetails, 62 | * 'price' => $paymentAmount, 63 | * 'quantity' => 1 64 | * ); 65 | * 66 | * $itemDetails = array( 67 | * $item1 68 | * ); 69 | * 70 | * $params = array( 71 | * 'paymentAmount' => $paymentAmount, 72 | * 'merchantOrderId' => $merchantOrderId, 73 | * 'productDetails' => $productDetails, 74 | * 'additionalParam' => $additionalParam, 75 | * 'merchantUserInfo' => $merchantUserInfo, 76 | * 'customerVaName' => $customerVaName, 77 | * 'email' => $email, 78 | * 'phoneNumber' => $phoneNumber, 79 | * 'itemDetails' => $itemDetails, 80 | * 'customerDetail' => $customerDetail, 81 | * 'callbackUrl' => $callbackUrl, 82 | * 'returnUrl' => $returnUrl, 83 | * 'expiryPeriod' => $expiryPeriod 84 | * ); 85 | * 86 | * try { 87 | * // createInvoice Request 88 | * $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $config); 89 | * 90 | * header('Content-Type: application/json'); 91 | * echo $responseDuitkuPop; 92 | * } catch (Exception $e) { 93 | * echo $e->getMessage(); 94 | * } 95 | * 96 | * ``` 97 | * @param array $payload 98 | * @param \Duitku\Config $config 99 | * @return string response duitku pop. 100 | * @throws Exception 101 | */ 102 | public static function createInvoice($payload, $config) 103 | { 104 | if ($config->getSanitizedMode()) { 105 | \Duitku\Sanitizer::request($payload); 106 | } 107 | 108 | $timestamp = round(microtime(true) * 1000); 109 | $signature = hash('sha256', $config->getMerchantCode() . $timestamp . $config->getApiKey()); 110 | 111 | $params = json_encode($payload); 112 | $header = array( 113 | 'x-duitku-signature:' . $signature, 114 | 'x-duitku-timestamp:' . $timestamp, 115 | 'x-duitku-merchantcode:' . $config->getMerchantCode() 116 | ); 117 | 118 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 119 | $url = $config->getBaseUrl() . '/api/merchant/createInvoice'; 120 | return self::sendRequest($url, $params, $config, $setLogFunction, $header); 121 | } 122 | 123 | /** 124 | * Cek Transaction Duitku Pop 125 | * 126 | * Example: 127 | * 128 | * ```php 129 | * 130 | * try { 131 | * $merchantOrderId = "YOUR_ORDER_ID"; 132 | * $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $config); 133 | * 134 | * header('Content-Type: application/json'); 135 | * echo json_encode($transactionList); 136 | * 137 | * if ($transaction->statusCode == "00") { 138 | * // Action Success 139 | * } else if ($transaction->statusCode == "01") { 140 | * // Action Pending 141 | * } else { 142 | * // Action Failed Or Expired 143 | * } 144 | * } 145 | * catch (Exception $e) { 146 | * echo $e->getMessage(); 147 | * } 148 | * ``` 149 | * 150 | * @param string $merchantOrderId 151 | * @param \Duitku\Config $config 152 | * @return string response cek status duitku pop. 153 | * @throws Exception 154 | */ 155 | public static function transactionStatus($merchantOrderId, $config) 156 | { 157 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 158 | 159 | $payload = array( 160 | 'merchantCode' => $config->getMerchantCode(), 161 | 'merchantOrderId' => $merchantOrderId, 162 | 'signature' => $signature 163 | ); 164 | 165 | $params = json_encode($payload); 166 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 167 | $url = $config->getBaseUrl() . '/api/merchant/transactionStatus'; 168 | return self::sendRequest($url, $params, $config, $setLogFunction); 169 | } 170 | 171 | /** 172 | * Get List Payment Method Duitku Pop 173 | * 174 | * Example: 175 | * 176 | * ```php 177 | * 178 | * try { 179 | * $paymentAmount = 10000; 180 | * $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $config); 181 | * 182 | * var_dump(paymentMethodList) 183 | * 184 | * } 185 | * catch (Exception $e) { 186 | * echo $e->getMessage(); 187 | * } 188 | * ``` 189 | * 190 | * @param \Duitku\Config $config 191 | * @return string response cek status duitku Pop. 192 | * @throws Exception 193 | */ 194 | public static function getPaymentMethod($paymentAmount, $config) 195 | { 196 | $datetime = date('Y-m-d H:i:s'); 197 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 198 | 199 | $payload = array( 200 | 'merchantCode' => $config->getMerchantCode(), 201 | 'amount' => $paymentAmount, 202 | 'datetime' => $datetime, 203 | 'signature' => $signature 204 | ); 205 | 206 | $params = json_encode($payload); 207 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 208 | 209 | // endpoint url api v2 210 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 211 | return self::sendRequest($url, $params, $config, $setLogFunction); 212 | } 213 | 214 | /** 215 | * Callback Duitku Pop 216 | * Handle Method HTTP POST => Type x-www-form-urlencoded 217 | * 218 | * Example 219 | * 220 | * try { 221 | * $callback = \Duitku\Pop::callback($config); 222 | * 223 | * header('Content-Type: application/json'); 224 | * $notif = json_decode($callback); 225 | * 226 | * if ($notif->resultCode == "00") { 227 | * // Action Success 228 | * } else if ($notif->resultCode == "01") { 229 | * // Action Pending 230 | * } else { 231 | * // Ignore 232 | * } 233 | * 234 | * } catch (Exception $e) { 235 | * http_response_code(400); 236 | * echo $e->getMessage(); 237 | * } 238 | * 239 | * @param \Duitku\Config $config 240 | * @return json response 241 | * @throws Exception 242 | */ 243 | public static function callback($config) 244 | { 245 | $notification = $_POST; 246 | if (empty($notification)) { 247 | throw new \Exception('Access denied'); 248 | } 249 | 250 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 251 | 252 | foreach ($config->callbackParams as $callbackParam) { 253 | if (!array_key_exists($callbackParam, $notification)) { 254 | $notification[$callbackParam] = null; 255 | } 256 | } 257 | 258 | if (!self::isSignatureValid($notification, $config)) { 259 | throw new \Exception('Signature Invalid'); 260 | } 261 | 262 | return json_encode($notification); 263 | } 264 | 265 | /** 266 | * Validation signature callback duitku pop 267 | * 268 | */ 269 | private static function isSignatureValid($notification, $config) 270 | { 271 | $signature = $notification['signature']; 272 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 273 | return $signature == $signGenerate; 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /Duitku/Request.php: -------------------------------------------------------------------------------- 1 | = 400) { 47 | throw new \Exception('Duitku Error: ' . $httpCode . ' response: ' . $response); 48 | } else { 49 | return $response; 50 | } 51 | } 52 | 53 | /** 54 | * Duitku write log parameter 55 | * 56 | * Please set => 57 | * $duitkuConfig = new \Duitku\Config(); 58 | * $duitkuConfig->setDuitkuLogs(true); // default true 59 | * 60 | */ 61 | protected static function writeDuitkuLogs($setLogFunction, $url, $method, $logRequest, $logResponse, $config) 62 | { 63 | if ($config->getDuitkuLogs()) { 64 | if (!empty($logRequest)) { 65 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 66 | self::writeLogs($config, "METHOD:" . $method); 67 | self::writeLogs($config, "FUNCTION:" . $setLogFunction); 68 | self::writeLogs($config, "URL:" . $url); 69 | self::writeLogs($config, "REQUEST:", $logRequest); 70 | self::writeLogs($config, "RESPONSE:", $logResponse . "\r\n"); 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * Duitku write log parameter for callback only 77 | * 78 | * Please set => 79 | * $duitkuConfig = new \Duitku\Config(); 80 | * $duitkuConfig->setDuitkuLogs(true); // default true 81 | * 82 | */ 83 | protected static function writeDuitkuLogsCallback($url, $logRequest, $config) 84 | { 85 | if ($config->getDuitkuLogs()) { 86 | if (!empty($logRequest)) { 87 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 88 | self::writeLogs($config, "URL:" . $url); 89 | self::writeLogs($config, "CALLBACK REQUEST:", $logRequest . "\r\n"); 90 | } 91 | } 92 | } 93 | 94 | /** 95 | * Write Log parameter 96 | * 97 | */ 98 | private static function writeLogs($config, $logTitle, $logMessage = '') 99 | { 100 | $rootDirLogs = __DIR__ . "/../logs/"; 101 | 102 | // create dir logs 103 | if (!is_dir($rootDirLogs)) 104 | mkdir($rootDirLogs); 105 | 106 | file_put_contents($rootDirLogs . $config->getLogFileName(), $logTitle . stripslashes($logMessage) . "\r\n", FILE_APPEND | LOCK_EX); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Duitku/Sanitizer.php: -------------------------------------------------------------------------------- 1 | "int|maxLength:50", 17 | "merchantOrderId" => "string|maxLength:50", 18 | "productDetails" => "string|maxLength:255", 19 | "additionalParam" => "string|maxLength:255", 20 | "merchantUserInfo" => "string|maxLength:255", 21 | "customerVaName" => "string|maxLength:20", 22 | "phoneNumber" => "string|maxLength:20|phone", 23 | "expiryPeriod" => "int", 24 | 25 | // itemDetails 26 | "name" => "string|maxLength:50", 27 | "quantity" => "int", 28 | "price" => "int", 29 | 30 | //billingAddress and shippingAddress 31 | 'firstName' => "string|maxLength:50", 32 | 'lastName' => "string|maxLength:50", 33 | 'address' => "string|maxLength:255", 34 | 'city' => "string|maxLength:50", 35 | 'postalCode' => "string|maxLength:50", 36 | 'phone' => "string|maxLength:20|phone", 37 | 'countryCode' => "string|maxLength:50" 38 | ); 39 | 40 | /** 41 | * 42 | * Example: 43 | * 44 | * ```php 45 | * 46 | * $params = array( 47 | * "example1" => "value1", 48 | * "example2" => "value2", 49 | * "example3" => "value3", 50 | * ); 51 | * 52 | * \Duitku\Sanitizer::request($params); 53 | * 54 | * ``` 55 | * 56 | * @param array &$parameterArray 57 | * @return void 58 | */ 59 | public static function Request(&$parameterArray) 60 | { 61 | if (!is_array($parameterArray)) { 62 | return; 63 | } 64 | 65 | foreach ($parameterArray as $rulesLabel => &$parameterValue) { 66 | if (is_array($parameterValue)) { 67 | // parse itemDetails and customerDetail 68 | foreach ($parameterValue as $rulesCustomerDetail => &$parameterCustomerDetail) { 69 | // parse billingAddress and shippingAddress 70 | self::loopParamAddress($parameterCustomerDetail); 71 | 72 | if (isset(self::$_rules[$rulesCustomerDetail])) { 73 | self::sanitizeValue(self::$_rules[$rulesCustomerDetail], $parameterCustomerDetail); 74 | } 75 | } 76 | } 77 | 78 | if (isset(self::$_rules[$rulesLabel])) { 79 | self::sanitizeValue(self::$_rules[$rulesLabel], $parameterValue); 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * Filter field "int|string|maxLength|phone" 86 | * 87 | * @param string $fieldName 88 | * @param string &$parameterValue 89 | * @return void 90 | */ 91 | private static function sanitizeValue($fieldName, &$parameterValue) 92 | { 93 | $attributeTags = explode('|', $fieldName); 94 | rsort($attributeTags); 95 | foreach ($attributeTags as $attributeTag) { 96 | $attributeTagValue = explode(':', $attributeTag); 97 | switch ($attributeTagValue[0]) { 98 | case "string": 99 | $parameterValue = (string)$parameterValue; 100 | break; 101 | case "int": 102 | $parameterValue = (int)$parameterValue; 103 | break; 104 | case "maxLength": 105 | $parameterValue = substr($parameterValue, 0, $attributeTagValue[1]); 106 | break; 107 | case "phone": 108 | $parameterValue = preg_replace("/[^\\d\\-\\(\\)]/", '', $parameterValue); 109 | break; 110 | } 111 | } 112 | } 113 | 114 | /** 115 | * Parse billingAddress and shippingAddress 116 | * 117 | * @param array &$parameterCustomerDetail 118 | * @return void 119 | */ 120 | private static function loopParamAddress(&$parameterCustomerDetail) 121 | { 122 | if (!is_array($parameterCustomerDetail)) { 123 | return; 124 | } 125 | 126 | foreach ($parameterCustomerDetail as $rulesAddress => &$parameterAddress) { 127 | self::sanitizeValue(self::$_rules[$rulesAddress], $parameterAddress); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Duitku PHP Library 2 | Welcome to Duitku PHP Example Project Implementation Page, Integrate this Duitku PHP to start transaction using Duitku in your Web or Application. 3 | 4 | 5 | ![flow_duitku_payment](https://user-images.githubusercontent.com/13087322/138187049-1a28ed5b-e9e8-48c9-aada-fa6f978c6e64.gif) 6 | 7 | 8 | 9 |

Demo Project

10 | Go To Demo Duitku-Pop 11 | 12 | Go To Demo Duitku-Api 13 | 14 | 15 |

Full Step Docs

16 | Go To Duitku Docs Duitku-Pop 17 | 18 | Go To Duitku Docs Duitku-Api 19 | 20 | ## Installation 21 | 22 | Install duitku-php with composer by following command: 23 | 24 | ```bash 25 | composer require duitkupg/duitku-php:dev-master 26 | ``` 27 | 28 | or add it manually in your `composer.json` file. 29 | 30 | ```bash 31 | "duitkupg/duitku-php": "dev-master" 32 | ``` 33 | ## Configuration Settings 34 | 35 | ```php 36 | $duitkuConfig = new \Duitku\Config("YOUR_MERCHANT_KEY", "YOUR_MERCHANT_CODE"); 37 | // false for production mode 38 | // true for sandbox mode 39 | $duitkuConfig->setSandboxMode(false); 40 | // set sanitizer (default : true) 41 | $duitkuConfig->setSanitizedMode(false); 42 | // set log parameter (default : true) 43 | $duitkuConfig->setDuitkuLogs(false); 44 | ``` 45 | 46 | ## Duitku POP 47 | ### Create Invoice (Duitku-Pop) 48 | 49 | Parameter paymentMethod is optional, 50 | 51 | You can put payment method('paymentMethod') on parameter createInvoice, as a step to set direct payment to specific payment. Customers will be directed to wanted payment without necessary to pick a payment. 52 | 53 | ```php 54 | // $paymentMethod = ""; // PaymentMethod list => https://docs.duitku.com/pop/id/#payment-method 55 | $paymentAmount = 10000; // Amount 56 | $email = "customer@gmail.com"; // your customer email 57 | $phoneNumber = "081234567890"; // your customer phone number (optional) 58 | $productDetails = "Test Payment"; 59 | $merchantOrderId = time(); // from merchant, unique 60 | $additionalParam = ''; // optional 61 | $merchantUserInfo = ''; // optional 62 | $customerVaName = 'John Doe'; // display name on bank confirmation display 63 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 64 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 65 | $expiryPeriod = 60; // set the expired time in minutes 66 | 67 | // Customer Detail 68 | $firstName = "John"; 69 | $lastName = "Doe"; 70 | 71 | // Address 72 | $alamat = "Jl. Kembangan Raya"; 73 | $city = "Jakarta"; 74 | $postalCode = "11530"; 75 | $countryCode = "ID"; 76 | 77 | $address = array( 78 | 'firstName' => $firstName, 79 | 'lastName' => $lastName, 80 | 'address' => $alamat, 81 | 'city' => $city, 82 | 'postalCode' => $postalCode, 83 | 'phone' => $phoneNumber, 84 | 'countryCode' => $countryCode 85 | ); 86 | 87 | $customerDetail = array( 88 | 'firstName' => $firstName, 89 | 'lastName' => $lastName, 90 | 'email' => $email, 91 | 'phoneNumber' => $phoneNumber, 92 | 'billingAddress' => $address, 93 | 'shippingAddress' => $address 94 | ); 95 | 96 | // Item Details 97 | $item1 = array( 98 | 'name' => $productDetails, 99 | 'price' => $paymentAmount, 100 | 'quantity' => 1 101 | ); 102 | 103 | $itemDetails = array( 104 | $item1 105 | ); 106 | 107 | $params = array( 108 | 'paymentAmount' => $paymentAmount, 109 | 'merchantOrderId' => $merchantOrderId, 110 | 'productDetails' => $productDetails, 111 | 'additionalParam' => $additionalParam, 112 | 'merchantUserInfo' => $merchantUserInfo, 113 | 'customerVaName' => $customerVaName, 114 | 'email' => $email, 115 | 'phoneNumber' => $phoneNumber, 116 | 'itemDetails' => $itemDetails, 117 | 'customerDetail' => $customerDetail, 118 | 'callbackUrl' => $callbackUrl, 119 | 'returnUrl' => $returnUrl, 120 | 'expiryPeriod' => $expiryPeriod 121 | ); 122 | 123 | try { 124 | // createInvoice Request 125 | $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $duitkuConfig); 126 | 127 | header('Content-Type: application/json'); 128 | echo $responseDuitkuPop; 129 | } catch (Exception $e) { 130 | echo $e->getMessage(); 131 | } 132 | ``` 133 | 134 | ### Check Transaction Status (Duitku-Pop) 135 | ```php 136 | try { 137 | $merchantOrderId = "YOUR_MERCHANTORDERID"; 138 | $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $duitkuConfig); 139 | 140 | header('Content-Type: application/json'); 141 | $transaction = json_decode($transactionList); 142 | 143 | // var_dump($transactionList); 144 | 145 | if ($transaction->statusCode == "00") { 146 | // Action Success 147 | } else if ($transaction->statusCode == "01") { 148 | // Action Pending 149 | } else { 150 | // Action Failed Or Expired 151 | } 152 | } catch (Exception $e) { 153 | echo $e->getMessage(); 154 | } 155 | ``` 156 | 157 | ### Callback (Duitku-Pop) 158 | ```php 159 | try { 160 | $callback = \Duitku\Pop::callback($duitkuConfig); 161 | 162 | header('Content-Type: application/json'); 163 | $notif = json_decode($callback); 164 | 165 | // var_dump($callback); 166 | 167 | if ($notif->resultCode == "00") { 168 | // Action Success 169 | } else if ($notif->resultCode == "01") { 170 | // Action Failed 171 | } 172 | } catch (Exception $e) { 173 | http_response_code(400); 174 | echo $e->getMessage(); 175 | } 176 | ``` 177 | 178 | ### Get Payment Method (Duitku-Pop) 179 | ```php 180 | try { 181 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 182 | $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $duitkuConfig); 183 | 184 | header('Content-Type: application/json'); 185 | echo $paymentMethodList; 186 | } catch (Exception $e) { 187 | echo $e->getMessage(); 188 | } 189 | ``` 190 | 191 | ### Frontend Integration (Duitku-Pop) 192 | ```bash 193 | $.ajax({ 194 | type: "POST", 195 | data:{ 196 | // paymentMethod: '', 197 | paymentAmount: amount, 198 | productDetail: productDetail, 199 | email: email, 200 | phoneNumber: phoneNumber 201 | }, 202 | url: 'http://domain.com/createInvoice.php', 203 | dataType: "json", 204 | cache: false, 205 | success: function (result) { 206 | console.log(result.reference); 207 | console.log(result); 208 | checkout.process(result.reference, { 209 | successEvent: function(result){ 210 | // Add Your Action 211 | console.log('success'); 212 | console.log(result); 213 | alert('Payment Success'); 214 | }, 215 | pendingEvent: function(result){ 216 | // Add Your Action 217 | console.log('pending'); 218 | console.log(result); 219 | alert('Payment Pending'); 220 | }, 221 | errorEvent: function(result){ 222 | // Add Your Action 223 | console.log('error'); 224 | console.log(result); 225 | alert('Payment Error'); 226 | }, 227 | closeEvent: function(result){ 228 | // Add Your Action 229 | console.log('customer closed the popup without finishing the payment'); 230 | console.log(result); 231 | alert('customer closed the popup without finishing the payment'); 232 | } 233 | }); 234 | } 235 | }); 236 | ``` 237 | 238 | ## Duitku API 239 | ### Create Invoice (Duitku-Api) 240 | ```php 241 | $paymentAmount = 10000; // Amount 242 | $paymentMethod = "BT"; // Permata Bank Virtual Account 243 | $email = "customer@gmail.com"; // your customer email 244 | $phoneNumber = "081234567890"; // your customer phone number (optional) 245 | $productDetails = "Test Payment"; 246 | $merchantOrderId = time(); // from merchant, unique 247 | $additionalParam = ''; // optional 248 | $merchantUserInfo = ''; // optional 249 | $customerVaName = 'John Doe'; // display name on bank confirmation display 250 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 251 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 252 | $expiryPeriod = 60; // set the expired time in minutes 253 | 254 | // Customer Detail 255 | $firstName = "John"; 256 | $lastName = "Doe"; 257 | 258 | // Address 259 | $alamat = "Jl. Kembangan Raya"; 260 | $city = "Jakarta"; 261 | $postalCode = "11530"; 262 | $countryCode = "ID"; 263 | 264 | $address = array( 265 | 'firstName' => $firstName, 266 | 'lastName' => $lastName, 267 | 'address' => $alamat, 268 | 'city' => $city, 269 | 'postalCode' => $postalCode, 270 | 'phone' => $phoneNumber, 271 | 'countryCode' => $countryCode 272 | ); 273 | 274 | $customerDetail = array( 275 | 'firstName' => $firstName, 276 | 'lastName' => $lastName, 277 | 'email' => $email, 278 | 'phoneNumber' => $phoneNumber, 279 | 'billingAddress' => $address, 280 | 'shippingAddress' => $address 281 | ); 282 | 283 | // Item Details 284 | $item1 = array( 285 | 'name' => $productDetails, 286 | 'price' => $paymentAmount, 287 | 'quantity' => 1 288 | ); 289 | 290 | $itemDetails = array( 291 | $item1 292 | ); 293 | 294 | $params = array( 295 | 'paymentAmount' => $paymentAmount, 296 | 'paymentMethod' => $paymentMethod, 297 | 'merchantOrderId' => $merchantOrderId, 298 | 'productDetails' => $productDetails, 299 | 'additionalParam' => $additionalParam, 300 | 'merchantUserInfo' => $merchantUserInfo, 301 | 'customerVaName' => $customerVaName, 302 | 'email' => $email, 303 | 'phoneNumber' => $phoneNumber, 304 | 'itemDetails' => $itemDetails, 305 | 'customerDetail' => $customerDetail, 306 | 'callbackUrl' => $callbackUrl, 307 | 'returnUrl' => $returnUrl, 308 | 'expiryPeriod' => $expiryPeriod 309 | ); 310 | 311 | try { 312 | // createInvoice Request 313 | $responseDuitkuApi = \Duitku\Api::createInvoice($params, $duitkuConfig); 314 | 315 | header('Content-Type: application/json'); 316 | echo $responseDuitkuApi; 317 | } catch (Exception $e) { 318 | echo $e->getMessage(); 319 | } 320 | ``` 321 | 322 | ### Check Transaction Status (Duitku-Api) 323 | ```php 324 | try { 325 | $merchantOrderId = "YOUR_MERCHANTORDERID"; 326 | $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $duitkuConfig); 327 | 328 | header('Content-Type: application/json'); 329 | $transaction = json_decode($transactionList); 330 | 331 | // var_dump($transactionList); 332 | 333 | if ($transaction->statusCode == "00") { 334 | // Action Success 335 | } else if ($transaction->statusCode == "01") { 336 | // Action Pending 337 | } else { 338 | // Action Failed Or Expired 339 | } 340 | } catch (Exception $e) { 341 | echo $e->getMessage(); 342 | } 343 | ``` 344 | 345 | ### Callback (Duitku-Api) 346 | ```php 347 | try { 348 | $callback = \Duitku\Api::callback($duitkuConfig); 349 | 350 | header('Content-Type: application/json'); 351 | $notif = json_decode($callback); 352 | 353 | // var_dump($callback); 354 | 355 | if ($notif->resultCode == "00") { 356 | // Action Success 357 | } else if ($notif->resultCode == "01") { 358 | // Action Failed 359 | } 360 | } catch (Exception $e) { 361 | http_response_code(400); 362 | echo $e->getMessage(); 363 | } 364 | ``` 365 | 366 | ### Get Payment Method (Duitku-Api) 367 | ```php 368 | try { 369 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 370 | $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $duitkuConfig); 371 | 372 | header('Content-Type: application/json'); 373 | echo $paymentMethodList; 374 | } catch (Exception $e) { 375 | echo $e->getMessage(); 376 | } 377 | ``` 378 | 379 | ## Tests 380 | 381 | ### Tests Duitku-Pop 382 | 383 | #### Create Invoice Test 384 | ```bash 385 | php vendor\bin\phpunit tests\CreateInvoiceTest.php 386 | ``` 387 | 388 | #### Transaction Status Test 389 | ```bash 390 | php vendor\bin\phpunit tests\TransactionStatusTest.php 391 | ``` 392 | 393 | #### Callback Test 394 | ```bash 395 | php vendor\bin\phpunit tests\CallbackTest.php 396 | ``` 397 | 398 | ### Tests Duitku-Api 399 | 400 | #### Create Invoice Api Test 401 | ```bash 402 | php vendor\bin\phpunit tests\CreateInvoiceApiTest.php 403 | ``` 404 | 405 | #### Transaction Status Api Test 406 | ```bash 407 | php vendor\bin\phpunit tests\TransactionStatusApiTest.php 408 | ``` 409 | 410 | #### Callback Api Test 411 | ```bash 412 | php vendor\bin\phpunit tests\CallbackApiTest.php 413 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duitkupg/duitku-php", 3 | "description": "Duitku PHP", 4 | "homepage": "https://duitku.com", 5 | "version": "1.0.0", 6 | "type": "library", 7 | "license": "MIT", 8 | "require": { 9 | "php": ">=5.6", 10 | "ext-curl": "*", 11 | "ext-json": "*" 12 | }, 13 | "require-dev": { 14 | "phpunit/phpunit": "7" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Duitku\\": "Duitku/" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /example/composer/Callback-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $callback = \Duitku\Api::callback($duitkuConfig); 11 | 12 | header('Content-Type: application/json'); 13 | $notif = json_decode($callback); 14 | 15 | // var_dump($callback); 16 | 17 | if ($notif->resultCode == "00") { 18 | // Action Success 19 | } else if ($notif->resultCode == "01") { 20 | // Action Failed 21 | } 22 | } catch (Exception $e) { 23 | http_response_code(400); 24 | echo $e->getMessage(); 25 | } 26 | -------------------------------------------------------------------------------- /example/composer/Callback.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $callback = \Duitku\Pop::callback($duitkuConfig); 11 | 12 | header('Content-Type: application/json'); 13 | $notif = json_decode($callback); 14 | 15 | // var_dump($callback); 16 | 17 | if ($notif->resultCode == "00") { 18 | // Action Success 19 | } else if ($notif->resultCode == "01") { 20 | // Action Failed 21 | } 22 | } catch (Exception $e) { 23 | http_response_code(400); 24 | echo $e->getMessage(); 25 | } 26 | -------------------------------------------------------------------------------- /example/composer/CreateInvoice-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | $paymentAmount = 10000; // Amount 10 | $paymentMethod = "BT"; // Permata Bank Virtual Account 11 | $email = "customer@gmail.com"; // your customer email 12 | $phoneNumber = "081234567890"; // your customer phone number (optional) 13 | $productDetails = "Test Payment"; 14 | $merchantOrderId = time(); // from merchant, unique 15 | $additionalParam = ''; // optional 16 | $merchantUserInfo = ''; // optional 17 | $customerVaName = 'John Doe'; // display name on bank confirmation display 18 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 19 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 20 | $expiryPeriod = 60; // set the expired time in minutes 21 | 22 | // Customer Detail 23 | $firstName = "John"; 24 | $lastName = "Doe"; 25 | 26 | // Address 27 | $alamat = "Jl. Kembangan Raya"; 28 | $city = "Jakarta"; 29 | $postalCode = "11530"; 30 | $countryCode = "ID"; 31 | 32 | $address = array( 33 | 'firstName' => $firstName, 34 | 'lastName' => $lastName, 35 | 'address' => $alamat, 36 | 'city' => $city, 37 | 'postalCode' => $postalCode, 38 | 'phone' => $phoneNumber, 39 | 'countryCode' => $countryCode 40 | ); 41 | 42 | $customerDetail = array( 43 | 'firstName' => $firstName, 44 | 'lastName' => $lastName, 45 | 'email' => $email, 46 | 'phoneNumber' => $phoneNumber, 47 | 'billingAddress' => $address, 48 | 'shippingAddress' => $address 49 | ); 50 | 51 | 52 | // Item Details 53 | $item1 = array( 54 | 'name' => $productDetails, 55 | 'price' => $paymentAmount, 56 | 'quantity' => 1 57 | ); 58 | 59 | 60 | $itemDetails = array( 61 | $item1 62 | ); 63 | 64 | $params = array( 65 | 'paymentAmount' => $paymentAmount, 66 | 'paymentMethod' => $paymentMethod, 67 | 'merchantOrderId' => $merchantOrderId, 68 | 'productDetails' => $productDetails, 69 | 'additionalParam' => $additionalParam, 70 | 'merchantUserInfo' => $merchantUserInfo, 71 | 'customerVaName' => $customerVaName, 72 | 'email' => $email, 73 | 'phoneNumber' => $phoneNumber, 74 | 'itemDetails' => $itemDetails, 75 | 'customerDetail' => $customerDetail, 76 | 'callbackUrl' => $callbackUrl, 77 | 'returnUrl' => $returnUrl, 78 | 'expiryPeriod' => $expiryPeriod 79 | ); 80 | 81 | try { 82 | // createInvoice Request 83 | $responseDuitkuApi = \Duitku\Api::createInvoice($params, $duitkuConfig); 84 | 85 | header('Content-Type: application/json'); 86 | 87 | $responseDuitku = json_decode($responseDuitkuApi); 88 | 89 | // var_dump($$responseDuitku); 90 | 91 | if ($responseDuitku->statusCode == "00") { 92 | header('location: ' . $responseDuitku->paymentUrl); 93 | } 94 | } catch (Exception $e) { 95 | echo $e->getMessage(); 96 | } 97 | -------------------------------------------------------------------------------- /example/composer/CreateInvoice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 23 |
24 | 25 |
26 |

Duitku Pop

27 |
28 |
29 | 30 |
31 | 32 | 34 |
35 | 36 |
37 | 38 | 40 |
41 | 42 |
43 | 44 | 46 |
47 | 48 |
49 | 50 | 52 |
53 | 54 |
55 | 56 | 60 |
61 | 62 | 64 | 65 |
66 | 67 |
68 |
69 | 70 | 71 | 72 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /example/composer/CreateInvoice.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | // Parameter PaymentMethod is optional 10 | // $paymentMethod = ""; // PaymentMethod list => https://docs.duitku.com/pop/id/#payment-method 11 | $paymentAmount = 10000; // Amount 12 | $email = "customer@gmail.com"; // your customer email 13 | $phoneNumber = "081234567890"; // your customer phone number (optional) 14 | $productDetails = "Test Payment"; 15 | $merchantOrderId = time(); // from merchant, unique 16 | $additionalParam = ''; // optional 17 | $merchantUserInfo = ''; // optional 18 | $customerVaName = 'John Doe'; // display name on bank confirmation display 19 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 20 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 21 | $expiryPeriod = 60; // set the expired time in minutes 22 | 23 | // Customer Detail 24 | $firstName = "John"; 25 | $lastName = "Doe"; 26 | 27 | // Address 28 | $alamat = "Jl. Kembangan Raya"; 29 | $city = "Jakarta"; 30 | $postalCode = "11530"; 31 | $countryCode = "ID"; 32 | 33 | $address = array( 34 | 'firstName' => $firstName, 35 | 'lastName' => $lastName, 36 | 'address' => $alamat, 37 | 'city' => $city, 38 | 'postalCode' => $postalCode, 39 | 'phone' => $phoneNumber, 40 | 'countryCode' => $countryCode 41 | ); 42 | 43 | $customerDetail = array( 44 | 'firstName' => $firstName, 45 | 'lastName' => $lastName, 46 | 'email' => $email, 47 | 'phoneNumber' => $phoneNumber, 48 | 'billingAddress' => $address, 49 | 'shippingAddress' => $address 50 | ); 51 | 52 | 53 | // Item Details 54 | $item1 = array( 55 | 'name' => $productDetails, 56 | 'price' => $paymentAmount, 57 | 'quantity' => 1 58 | ); 59 | 60 | 61 | $itemDetails = array( 62 | $item1 63 | ); 64 | 65 | $params = array( 66 | 'paymentAmount' => $paymentAmount, 67 | 'merchantOrderId' => $merchantOrderId, 68 | 'productDetails' => $productDetails, 69 | 'additionalParam' => $additionalParam, 70 | 'merchantUserInfo' => $merchantUserInfo, 71 | 'customerVaName' => $customerVaName, 72 | 'email' => $email, 73 | 'phoneNumber' => $phoneNumber, 74 | 'itemDetails' => $itemDetails, 75 | 'customerDetail' => $customerDetail, 76 | 'callbackUrl' => $callbackUrl, 77 | 'returnUrl' => $returnUrl, 78 | 'expiryPeriod' => $expiryPeriod 79 | ); 80 | 81 | try { 82 | // createInvoice Request 83 | $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $duitkuConfig); 84 | 85 | header('Content-Type: application/json'); 86 | echo $responseDuitkuPop; 87 | } catch (Exception $e) { 88 | echo $e->getMessage(); 89 | } 90 | -------------------------------------------------------------------------------- /example/composer/GetPaymentMethod-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 11 | $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | echo $paymentMethodList; 15 | } catch (Exception $e) { 16 | echo $e->getMessage(); 17 | } 18 | -------------------------------------------------------------------------------- /example/composer/GetPaymentMethod.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 11 | $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | echo $paymentMethodList; 15 | } catch (Exception $e) { 16 | echo $e->getMessage(); 17 | } 18 | -------------------------------------------------------------------------------- /example/composer/TransactionStatus-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 11 | $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | $transaction = json_decode($transactionList); 15 | 16 | // var_dump($transactionList); 17 | 18 | if ($transaction->statusCode == "00") { 19 | // Action Success 20 | } else if ($transaction->statusCode == "01") { 21 | // Action Pending 22 | } else { 23 | // Action Failed Or Expired 24 | } 25 | } catch (Exception $e) { 26 | echo $e->getMessage(); 27 | } 28 | -------------------------------------------------------------------------------- /example/composer/TransactionStatus.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 11 | $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | $transaction = json_decode($transactionList); 15 | 16 | // var_dump($transactionList); 17 | 18 | if ($transaction->statusCode == "00") { 19 | // Action Success 20 | } else if ($transaction->statusCode == "01") { 21 | // Action Pending 22 | } else { 23 | // Action Failed Or Expired 24 | } 25 | } catch (Exception $e) { 26 | echo $e->getMessage(); 27 | } 28 | -------------------------------------------------------------------------------- /example/composer/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duitkupg/duitku-php", 3 | "description": "Duitku PHP", 4 | "homepage": "https://duitku.com", 5 | "version": "1.0.0", 6 | "type": "library", 7 | "license": "MIT", 8 | "require": { 9 | "php": ">=5.6", 10 | "ext-curl": "*", 11 | "ext-json": "*" 12 | }, 13 | "require-dev": { 14 | "phpunit/phpunit": "7" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Duitku\\": "Duitku/" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /example/env/.env: -------------------------------------------------------------------------------- 1 | SANDBOX_KEY=732B39FC61796845775D2C4FB05332AF 2 | SANDBOX_MERCHANTCODE=D0001 3 | 4 | PRODUCTION_KEY=732B39FC61796845775D2C4FB05332AF 5 | PRODUCTION_MERCHANTCODE=D0001 6 | 7 | SANDBOX_MODE=true 8 | -------------------------------------------------------------------------------- /example/env/Callback-Api.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $callback = \Duitku\Api::callback($duitkuConfig); 24 | 25 | header('Content-Type: application/json'); 26 | $notif = json_decode($callback); 27 | 28 | // var_dump($callback); 29 | 30 | if ($notif->resultCode == "00") { 31 | // Action Success 32 | } else if ($notif->resultCode == "01") { 33 | // Action Failed 34 | } 35 | } catch (Exception $e) { 36 | http_response_code(400); 37 | echo $e->getMessage(); 38 | } 39 | -------------------------------------------------------------------------------- /example/env/Callback.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $callback = \Duitku\Pop::callback($duitkuConfig); 24 | 25 | header('Content-Type: application/json'); 26 | $notif = json_decode($callback); 27 | 28 | // var_dump($callback); 29 | 30 | if ($notif->resultCode == "00") { 31 | // Action Success 32 | } else if ($notif->resultCode == "01") { 33 | // Action Failed 34 | } 35 | } catch (Exception $e) { 36 | http_response_code(400); 37 | echo $e->getMessage(); 38 | } 39 | -------------------------------------------------------------------------------- /example/env/CreateInvoice-Api.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | $paymentAmount = 10000; // Amount 23 | $paymentMethod = "BT"; // Permata Bank Virtual Account 24 | $email = "customer@gmail.com"; // your customer email 25 | $phoneNumber = "081234567890"; // your customer phone number (optional) 26 | $productDetails = "Test Payment"; 27 | $merchantOrderId = time(); // from merchant, unique 28 | $additionalParam = ''; // optional 29 | $merchantUserInfo = ''; // optional 30 | $customerVaName = 'John Doe'; // display name on bank confirmation display 31 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 32 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 33 | $expiryPeriod = 60; // set the expired time in minutes 34 | 35 | // Customer Detail 36 | $firstName = "John"; 37 | $lastName = "Doe"; 38 | 39 | // Address 40 | $alamat = "Jl. Kembangan Raya"; 41 | $city = "Jakarta"; 42 | $postalCode = "11530"; 43 | $countryCode = "ID"; 44 | 45 | $address = array( 46 | 'firstName' => $firstName, 47 | 'lastName' => $lastName, 48 | 'address' => $alamat, 49 | 'city' => $city, 50 | 'postalCode' => $postalCode, 51 | 'phone' => $phoneNumber, 52 | 'countryCode' => $countryCode 53 | ); 54 | 55 | $customerDetail = array( 56 | 'firstName' => $firstName, 57 | 'lastName' => $lastName, 58 | 'email' => $email, 59 | 'phoneNumber' => $phoneNumber, 60 | 'billingAddress' => $address, 61 | 'shippingAddress' => $address 62 | ); 63 | 64 | 65 | // Item Details 66 | $item1 = array( 67 | 'name' => $productDetails, 68 | 'price' => $paymentAmount, 69 | 'quantity' => 1 70 | ); 71 | 72 | 73 | $itemDetails = array( 74 | $item1 75 | ); 76 | 77 | $params = array( 78 | 'paymentAmount' => $paymentAmount, 79 | 'paymentMethod' => $paymentMethod, 80 | 'merchantOrderId' => $merchantOrderId, 81 | 'productDetails' => $productDetails, 82 | 'additionalParam' => $additionalParam, 83 | 'merchantUserInfo' => $merchantUserInfo, 84 | 'customerVaName' => $customerVaName, 85 | 'email' => $email, 86 | 'phoneNumber' => $phoneNumber, 87 | 'itemDetails' => $itemDetails, 88 | 'customerDetail' => $customerDetail, 89 | 'callbackUrl' => $callbackUrl, 90 | 'returnUrl' => $returnUrl, 91 | 'expiryPeriod' => $expiryPeriod 92 | ); 93 | 94 | try { 95 | // createInvoice Request 96 | $responseDuitkuApi = \Duitku\Api::createInvoice($params, $duitkuConfig); 97 | 98 | header('Content-Type: application/json'); 99 | 100 | $responseDuitku = json_decode($responseDuitkuApi); 101 | 102 | // var_dump($$responseDuitku); 103 | 104 | if ($responseDuitku->statusCode == "00") { 105 | header('location: ' . $responseDuitku->paymentUrl); 106 | } 107 | } catch (Exception $e) { 108 | echo $e->getMessage(); 109 | } 110 | -------------------------------------------------------------------------------- /example/env/CreateInvoice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 23 |
24 | 25 |
26 |

Duitku Pop

27 |
28 |
29 | 30 |
31 | 32 | 34 |
35 | 36 |
37 | 38 | 40 |
41 | 42 |
43 | 44 | 46 |
47 | 48 |
49 | 50 | 52 |
53 | 54 |
55 | 56 | 60 |
61 | 62 | 64 | 65 |
66 | 67 |
68 |
69 | 70 | 71 | 72 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /example/env/CreateInvoice.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | // Parameter PaymentMethod is optional 23 | // $paymentMethod = ""; // PaymentMethod list => https://docs.duitku.com/pop/id/#payment-method 24 | $paymentAmount = 10000; // Amount 25 | $email = "customer@gmail.com"; // your customer email 26 | $phoneNumber = "081234567890"; // your customer phone number (optional) 27 | $productDetails = "Test Payment"; 28 | $merchantOrderId = time(); // from merchant, unique 29 | $additionalParam = ''; // optional 30 | $merchantUserInfo = ''; // optional 31 | $customerVaName = 'John Doe'; // display name on bank confirmation display 32 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 33 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 34 | $expiryPeriod = 60; // set the expired time in minutes 35 | 36 | // Customer Detail 37 | $firstName = "John"; 38 | $lastName = "Doe"; 39 | 40 | // Address 41 | $alamat = "Jl. Kembangan Raya"; 42 | $city = "Jakarta"; 43 | $postalCode = "11530"; 44 | $countryCode = "ID"; 45 | 46 | $address = array( 47 | 'firstName' => $firstName, 48 | 'lastName' => $lastName, 49 | 'address' => $alamat, 50 | 'city' => $city, 51 | 'postalCode' => $postalCode, 52 | 'phone' => $phoneNumber, 53 | 'countryCode' => $countryCode 54 | ); 55 | 56 | $customerDetail = array( 57 | 'firstName' => $firstName, 58 | 'lastName' => $lastName, 59 | 'email' => $email, 60 | 'phoneNumber' => $phoneNumber, 61 | 'billingAddress' => $address, 62 | 'shippingAddress' => $address 63 | ); 64 | 65 | 66 | // Item Details 67 | $item1 = array( 68 | 'name' => $productDetails, 69 | 'price' => $paymentAmount, 70 | 'quantity' => 1 71 | ); 72 | 73 | 74 | $itemDetails = array( 75 | $item1 76 | ); 77 | 78 | $params = array( 79 | 'paymentAmount' => $paymentAmount, 80 | 'merchantOrderId' => $merchantOrderId, 81 | 'productDetails' => $productDetails, 82 | 'additionalParam' => $additionalParam, 83 | 'merchantUserInfo' => $merchantUserInfo, 84 | 'customerVaName' => $customerVaName, 85 | 'email' => $email, 86 | 'phoneNumber' => $phoneNumber, 87 | 'itemDetails' => $itemDetails, 88 | 'customerDetail' => $customerDetail, 89 | 'callbackUrl' => $callbackUrl, 90 | 'returnUrl' => $returnUrl, 91 | 'expiryPeriod' => $expiryPeriod 92 | ); 93 | 94 | try { 95 | // createInvoice Request 96 | $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $duitkuConfig); 97 | 98 | header('Content-Type: application/json'); 99 | echo $responseDuitkuPop; 100 | } catch (Exception $e) { 101 | echo $e->getMessage(); 102 | } 103 | -------------------------------------------------------------------------------- /example/env/Duitku.php: -------------------------------------------------------------------------------- 1 | = 5.6 required'); 8 | } 9 | 10 | // Check PHP Curl & 11 | if (!function_exists('curl_init') || !function_exists('curl_exec')) { 12 | throw new Exception('Duitku::cURL library is required'); 13 | } 14 | 15 | // Json decode capabilities. 16 | if (!function_exists('json_decode')) { 17 | throw new Exception('Duitku::JSON PHP extension is required'); 18 | } 19 | 20 | // Configuration Duitku Config 21 | require_once 'Duitku/Config.php'; 22 | // Duitku Sanitizer Parameter 23 | require_once 'Duitku/Sanitizer.php'; 24 | // Duitku Request Curl 25 | require_once 'Duitku/Request.php'; 26 | // General Duitku-Pop Request 27 | require_once 'Duitku/Pop.php'; 28 | // General Duitku-API Request 29 | require_once 'Duitku/Api.php'; 30 | -------------------------------------------------------------------------------- /example/env/Duitku/Api.php: -------------------------------------------------------------------------------- 1 | $firstName, 43 | * 'lastName' => $lastName, 44 | * 'address' => $alamat, 45 | * 'city' => $city, 46 | * 'postalCode' => $postalCode, 47 | * 'phone' => $phoneNumber, 48 | * 'countryCode' => $countryCode 49 | * ); 50 | * 51 | * $customerDetail = array( 52 | * 'firstName' => $firstName, 53 | * 'lastName' => $lastName, 54 | * 'email' => $email, 55 | * 'phoneNumber' => $phoneNumber, 56 | * 'billingAddress' => $address, 57 | * 'shippingAddress' => $address 58 | * ); 59 | * 60 | * // Item Details 61 | * $item1 = array( 62 | * 'name' => $productDetails, 63 | * 'price' => $paymentAmount, 64 | * 'quantity' => 1 65 | * ); 66 | * 67 | * $itemDetails = array( 68 | * $item1 69 | * ); 70 | * 71 | * $params = array( 72 | * 'paymentAmount' => $paymentAmount, 73 | * 'paymentMethod' => $paymentMethod, 74 | * 'merchantOrderId' => $merchantOrderId, 75 | * 'productDetails' => $productDetails, 76 | * 'additionalParam' => $additionalParam, 77 | * 'merchantUserInfo' => $merchantUserInfo, 78 | * 'customerVaName' => $customerVaName, 79 | * 'email' => $email, 80 | * 'phoneNumber' => $phoneNumber, 81 | * 'itemDetails' => $itemDetails, 82 | * 'customerDetail' => $customerDetail, 83 | * 'callbackUrl' => $callbackUrl, 84 | * 'returnUrl' => $returnUrl, 85 | * 'expiryPeriod' => $expiryPeriod 86 | * ); 87 | * 88 | * try { 89 | * // createInvoice Request 90 | * $responseDuitkuApi = \Duitku\Api::createInvoice($params, $config); 91 | * 92 | * header('Content-Type: application/json'); 93 | * echo $responseDuitkuApi; 94 | * } catch (Exception $e) { 95 | * echo $e->getMessage(); 96 | * } 97 | * 98 | * ``` 99 | * @param array $payload 100 | * @param \Duitku\Config $config 101 | * @return string response duitku API. 102 | * @throws Exception 103 | */ 104 | public static function createInvoice($payload, $config) 105 | { 106 | if ($config->getSanitizedMode()) { 107 | \Duitku\Sanitizer::request($payload); 108 | } 109 | 110 | $timestamp = round(microtime(true) * 1000); 111 | $payload["merchantCode"] = $config->getMerchantCode(); 112 | $payload["signature"] = md5($config->getMerchantCode() . $payload["merchantOrderId"] . $payload["paymentAmount"] . $config->getApiKey()); 113 | 114 | $params = json_encode($payload); 115 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 116 | $url = $config->getApiUrl() . '/webapi/api/merchant/v2/inquiry'; 117 | return self::sendRequest($url, $params, $config, $setLogFunction); 118 | } 119 | 120 | /** 121 | * Cek Transaction Duitku API 122 | * 123 | * Example: 124 | * 125 | * ```php 126 | * 127 | * try { 128 | * $merchantOrderId = "YOUR_ORDER_ID"; 129 | * $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $config); 130 | * 131 | * header('Content-Type: application/json'); 132 | * echo json_encode($transactionList); 133 | * 134 | * if ($transaction->statusCode == "00") { 135 | * // Action Success 136 | * } else if ($transaction->statusCode == "01") { 137 | * // Action Pending 138 | * } else { 139 | * // Action Failed Or Expired 140 | * } 141 | * } 142 | * catch (Exception $e) { 143 | * echo $e->getMessage(); 144 | * } 145 | * ``` 146 | * 147 | * @param string $merchantOrderId 148 | * @param \Duitku\Config $config 149 | * @return string response cek status duitku API. 150 | * @throws Exception 151 | */ 152 | public static function transactionStatus($merchantOrderId, $config) 153 | { 154 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 155 | 156 | $payload = array( 157 | 'merchantCode' => $config->getMerchantCode(), 158 | 'merchantOrderId' => $merchantOrderId, 159 | 'signature' => $signature 160 | ); 161 | 162 | $params = json_encode($payload); 163 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 164 | $url = $config->getApiUrl() . '/webapi/api/merchant/transactionStatus'; 165 | return self::sendRequest($url, $params, $config, $setLogFunction); 166 | } 167 | 168 | /** 169 | * Get List Payment Method Duitku API 170 | * 171 | * Example: 172 | * 173 | * ```php 174 | * 175 | * try { 176 | * $paymentAmount = 10000; 177 | * $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $config); 178 | * 179 | * var_dump(paymentMethodList) 180 | * 181 | * } 182 | * catch (Exception $e) { 183 | * echo $e->getMessage(); 184 | * } 185 | * ``` 186 | * 187 | * @param \Duitku\Config $config 188 | * @return string response cek status duitku API. 189 | * @throws Exception 190 | */ 191 | public static function getPaymentMethod($paymentAmount, $config) 192 | { 193 | $datetime = date('Y-m-d H:i:s'); 194 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 195 | 196 | $payload = array( 197 | 'merchantCode' => $config->getMerchantCode(), 198 | 'amount' => $paymentAmount, 199 | 'datetime' => $datetime, 200 | 'signature' => $signature 201 | ); 202 | 203 | $params = json_encode($payload); 204 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 205 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 206 | return self::sendRequest($url, $params, $config, $setLogFunction); 207 | } 208 | 209 | /** 210 | * Callback Duitku API 211 | * Handle Method HTTP POST => Type x-www-form-urlencoded 212 | * 213 | * Example 214 | * 215 | * try { 216 | * $callback = \Duitku\Api::callback($config); 217 | * 218 | * header('Content-Type: application/json'); 219 | * $notif = json_decode($callback); 220 | * 221 | * if ($notif->resultCode == "00") { 222 | * // Action Success 223 | * } else if ($notif->resultCode == "01") { 224 | * // Action Pending 225 | * } else { 226 | * // Ignore 227 | * } 228 | * 229 | * } catch (Exception $e) { 230 | * http_response_code(400); 231 | * echo $e->getMessage(); 232 | * } 233 | * 234 | * @param \Duitku\Config $config 235 | * @return json response 236 | * @throws Exception 237 | */ 238 | public static function callback($config) 239 | { 240 | $notification = $_POST; 241 | if (empty($notification)) { 242 | throw new \Exception('Access denied'); 243 | } 244 | 245 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 246 | 247 | foreach ($config->callbackParams as $callbackParam) { 248 | if (!array_key_exists($callbackParam, $notification)) { 249 | $notification[$callbackParam] = null; 250 | } 251 | } 252 | 253 | if (!self::isSignatureValid($notification, $config)) { 254 | throw new \Exception('Signature Invalid'); 255 | } 256 | 257 | return json_encode($notification); 258 | } 259 | 260 | /** 261 | * Validation signature callback duitku API 262 | * 263 | */ 264 | private static function isSignatureValid($notification, $config) 265 | { 266 | $signature = $notification['signature']; 267 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 268 | return $signature == $signGenerate; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /example/env/Duitku/Config.php: -------------------------------------------------------------------------------- 1 | _apiKey = $apiKey; 22 | $this->_merchantCode = $merchantCode; 23 | $this->_isSandboxMode = $isSandboxMode; 24 | $this->_isSanitizedMode = $isSanitizedMode; 25 | $this->_duitkuLogs = $duitkuLogs; 26 | } 27 | 28 | /** 29 | * Your merchant's api key 30 | * 31 | */ 32 | private $_apiKey; 33 | /** 34 | * Your merchant's merchant code 35 | * 36 | */ 37 | private $_merchantCode; 38 | /** 39 | * false for production 40 | * true for sandbox 41 | * 42 | */ 43 | private $_isSandboxMode; 44 | /** 45 | * Enable request params sanitized mode / default true 46 | * 47 | */ 48 | private $_isSanitizedMode; 49 | /** 50 | * Set it true to enable log file 51 | * 52 | */ 53 | private $_duitkuLogs; 54 | 55 | /** 56 | * Set Callback Parameter 57 | * 58 | */ 59 | public $callbackParams = array( 60 | "merchantCode", 61 | "amount", 62 | "merchantOrderId", 63 | "productDetail", 64 | "additionalParam", 65 | "paymentCode", 66 | "resultCode", 67 | "merchantUserId", 68 | "reference", 69 | "signature", 70 | "spUserHash" 71 | ); 72 | 73 | const SANDBOX_URL = 'https://api-sandbox.duitku.com'; 74 | const PASSPORT_URL = 'https://api-prod.duitku.com'; 75 | 76 | const SANDBOX_API_URL = 'https://sandbox.duitku.com'; 77 | const PASSPORT_API_URL = 'https://passport.duitku.com'; 78 | 79 | /** 80 | * Set apiKey config 81 | * 82 | */ 83 | public function setApiKey($apiKey) 84 | { 85 | $this->_apiKey = $apiKey; 86 | } 87 | 88 | /** 89 | * Get apiKey config 90 | * 91 | */ 92 | public function getApiKey() 93 | { 94 | return $this->_apiKey; 95 | } 96 | 97 | /** 98 | * Set merchantCode config 99 | * 100 | */ 101 | public function setMerchantCode($merchantCode) 102 | { 103 | $this->_merchantCode = $merchantCode; 104 | } 105 | 106 | /** 107 | * Get merchantCode config 108 | * 109 | */ 110 | public function getMerchantCode() 111 | { 112 | return $this->_merchantCode; 113 | } 114 | 115 | /** 116 | * Set sandboxMode config 117 | * 118 | */ 119 | public function setSandboxMode($isSandboxMode) 120 | { 121 | $this->_isSandboxMode = $isSandboxMode; 122 | } 123 | 124 | /** 125 | * Get sandboxMode config 126 | * 127 | */ 128 | public function getSandboxMode() 129 | { 130 | return $this->_isSandboxMode; 131 | } 132 | 133 | /** 134 | * Set sanitizedMode config 135 | * 136 | */ 137 | public function setSanitizedMode($isSanitizedMode) 138 | { 139 | $this->_isSanitizedMode = $isSanitizedMode; 140 | } 141 | 142 | /** 143 | * Get sanitizedMode config 144 | * 145 | */ 146 | public function getSanitizedMode() 147 | { 148 | return $this->_isSanitizedMode; 149 | } 150 | 151 | /** 152 | * Set duitkuLogs config 153 | * 154 | */ 155 | public function setDuitkuLogs($duitkuLogs) 156 | { 157 | $this->_duitkuLogs = $duitkuLogs; 158 | } 159 | 160 | /** 161 | * Get duitkuLogs config 162 | * 163 | */ 164 | public function getDuitkuLogs() 165 | { 166 | return $this->_duitkuLogs; 167 | } 168 | 169 | /** 170 | * Get apiUrl 171 | * 172 | * @return Duitku API URL, depends on $_isSandboxMode 173 | */ 174 | public function getApiUrl() 175 | { 176 | if ($this->getSandboxMode()) { 177 | return self::SANDBOX_API_URL; 178 | } else { 179 | return self::PASSPORT_API_URL; 180 | } 181 | } 182 | 183 | /** 184 | * Get baseUrl 185 | * 186 | * @return Duitku POP URL, depends on $_isSandboxMode 187 | */ 188 | public function getBaseUrl() 189 | { 190 | if ($this->getSandboxMode()) { 191 | return self::SANDBOX_URL; 192 | } else { 193 | return self::PASSPORT_URL; 194 | } 195 | } 196 | 197 | /** 198 | * Generate string log file name 199 | * 200 | * @return string 201 | */ 202 | public function getLogFileName() 203 | { 204 | $logFileName = "duitku_" . date('Ymd') . ".log"; 205 | return $logFileName; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /example/env/Duitku/Pop.php: -------------------------------------------------------------------------------- 1 | $firstName, 42 | * 'lastName' => $lastName, 43 | * 'address' => $alamat, 44 | * 'city' => $city, 45 | * 'postalCode' => $postalCode, 46 | * 'phone' => $phoneNumber, 47 | * 'countryCode' => $countryCode 48 | * ); 49 | * 50 | * $customerDetail = array( 51 | * 'firstName' => $firstName, 52 | * 'lastName' => $lastName, 53 | * 'email' => $email, 54 | * 'phoneNumber' => $phoneNumber, 55 | * 'billingAddress' => $address, 56 | * 'shippingAddress' => $address 57 | * ); 58 | * 59 | * // Item Details 60 | * $item1 = array( 61 | * 'name' => $productDetails, 62 | * 'price' => $paymentAmount, 63 | * 'quantity' => 1 64 | * ); 65 | * 66 | * $itemDetails = array( 67 | * $item1 68 | * ); 69 | * 70 | * $params = array( 71 | * 'paymentAmount' => $paymentAmount, 72 | * 'merchantOrderId' => $merchantOrderId, 73 | * 'productDetails' => $productDetails, 74 | * 'additionalParam' => $additionalParam, 75 | * 'merchantUserInfo' => $merchantUserInfo, 76 | * 'customerVaName' => $customerVaName, 77 | * 'email' => $email, 78 | * 'phoneNumber' => $phoneNumber, 79 | * 'itemDetails' => $itemDetails, 80 | * 'customerDetail' => $customerDetail, 81 | * 'callbackUrl' => $callbackUrl, 82 | * 'returnUrl' => $returnUrl, 83 | * 'expiryPeriod' => $expiryPeriod 84 | * ); 85 | * 86 | * try { 87 | * // createInvoice Request 88 | * $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $config); 89 | * 90 | * header('Content-Type: application/json'); 91 | * echo $responseDuitkuPop; 92 | * } catch (Exception $e) { 93 | * echo $e->getMessage(); 94 | * } 95 | * 96 | * ``` 97 | * @param array $payload 98 | * @param \Duitku\Config $config 99 | * @return string response duitku pop. 100 | * @throws Exception 101 | */ 102 | public static function createInvoice($payload, $config) 103 | { 104 | if ($config->getSanitizedMode()) { 105 | \Duitku\Sanitizer::request($payload); 106 | } 107 | 108 | $timestamp = round(microtime(true) * 1000); 109 | $signature = hash('sha256', $config->getMerchantCode() . $timestamp . $config->getApiKey()); 110 | 111 | $params = json_encode($payload); 112 | $header = array( 113 | 'x-duitku-signature:' . $signature, 114 | 'x-duitku-timestamp:' . $timestamp, 115 | 'x-duitku-merchantcode:' . $config->getMerchantCode() 116 | ); 117 | 118 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 119 | $url = $config->getBaseUrl() . '/api/merchant/createInvoice'; 120 | return self::sendRequest($url, $params, $config, $setLogFunction, $header); 121 | } 122 | 123 | /** 124 | * Cek Transaction Duitku Pop 125 | * 126 | * Example: 127 | * 128 | * ```php 129 | * 130 | * try { 131 | * $merchantOrderId = "YOUR_ORDER_ID"; 132 | * $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $config); 133 | * 134 | * header('Content-Type: application/json'); 135 | * echo json_encode($transactionList); 136 | * 137 | * if ($transaction->statusCode == "00") { 138 | * // Action Success 139 | * } else if ($transaction->statusCode == "01") { 140 | * // Action Pending 141 | * } else { 142 | * // Action Failed Or Expired 143 | * } 144 | * } 145 | * catch (Exception $e) { 146 | * echo $e->getMessage(); 147 | * } 148 | * ``` 149 | * 150 | * @param string $merchantOrderId 151 | * @param \Duitku\Config $config 152 | * @return string response cek status duitku pop. 153 | * @throws Exception 154 | */ 155 | public static function transactionStatus($merchantOrderId, $config) 156 | { 157 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 158 | 159 | $payload = array( 160 | 'merchantCode' => $config->getMerchantCode(), 161 | 'merchantOrderId' => $merchantOrderId, 162 | 'signature' => $signature 163 | ); 164 | 165 | $params = json_encode($payload); 166 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 167 | $url = $config->getBaseUrl() . '/api/merchant/transactionStatus'; 168 | return self::sendRequest($url, $params, $config, $setLogFunction); 169 | } 170 | 171 | /** 172 | * Get List Payment Method Duitku Pop 173 | * 174 | * Example: 175 | * 176 | * ```php 177 | * 178 | * try { 179 | * $paymentAmount = 10000; 180 | * $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $config); 181 | * 182 | * var_dump(paymentMethodList) 183 | * 184 | * } 185 | * catch (Exception $e) { 186 | * echo $e->getMessage(); 187 | * } 188 | * ``` 189 | * 190 | * @param \Duitku\Config $config 191 | * @return string response cek status duitku Pop. 192 | * @throws Exception 193 | */ 194 | public static function getPaymentMethod($paymentAmount, $config) 195 | { 196 | $datetime = date('Y-m-d H:i:s'); 197 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 198 | 199 | $payload = array( 200 | 'merchantCode' => $config->getMerchantCode(), 201 | 'amount' => $paymentAmount, 202 | 'datetime' => $datetime, 203 | 'signature' => $signature 204 | ); 205 | 206 | $params = json_encode($payload); 207 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 208 | 209 | // endpoint url api v2 210 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 211 | return self::sendRequest($url, $params, $config, $setLogFunction); 212 | } 213 | 214 | /** 215 | * Callback Duitku Pop 216 | * Handle Method HTTP POST => Type x-www-form-urlencoded 217 | * 218 | * Example 219 | * 220 | * try { 221 | * $callback = \Duitku\Pop::callback($config); 222 | * 223 | * header('Content-Type: application/json'); 224 | * $notif = json_decode($callback); 225 | * 226 | * if ($notif->resultCode == "00") { 227 | * // Action Success 228 | * } else if ($notif->resultCode == "01") { 229 | * // Action Pending 230 | * } else { 231 | * // Ignore 232 | * } 233 | * 234 | * } catch (Exception $e) { 235 | * http_response_code(400); 236 | * echo $e->getMessage(); 237 | * } 238 | * 239 | * @param \Duitku\Config $config 240 | * @return json response 241 | * @throws Exception 242 | */ 243 | public static function callback($config) 244 | { 245 | $notification = $_POST; 246 | if (empty($notification)) { 247 | throw new \Exception('Access denied'); 248 | } 249 | 250 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 251 | 252 | foreach ($config->callbackParams as $callbackParam) { 253 | if (!array_key_exists($callbackParam, $notification)) { 254 | $notification[$callbackParam] = null; 255 | } 256 | } 257 | 258 | if (!self::isSignatureValid($notification, $config)) { 259 | throw new \Exception('Signature Invalid'); 260 | } 261 | 262 | return json_encode($notification); 263 | } 264 | 265 | /** 266 | * Validation signature callback duitku pop 267 | * 268 | */ 269 | private static function isSignatureValid($notification, $config) 270 | { 271 | $signature = $notification['signature']; 272 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 273 | return $signature == $signGenerate; 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /example/env/Duitku/Request.php: -------------------------------------------------------------------------------- 1 | = 400) { 47 | throw new \Exception('Duitku Error: ' . $httpCode . ' response: ' . $response); 48 | } else { 49 | return $response; 50 | } 51 | } 52 | 53 | /** 54 | * Duitku write log parameter 55 | * 56 | * Please set => 57 | * $duitkuConfig = new \Duitku\Config(); 58 | * $duitkuConfig->setDuitkuLogs(true); // default true 59 | * 60 | */ 61 | protected static function writeDuitkuLogs($setLogFunction, $url, $method, $logRequest, $logResponse, $config) 62 | { 63 | if ($config->getDuitkuLogs()) { 64 | if (!empty($logRequest)) { 65 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 66 | self::writeLogs($config, "METHOD:" . $method); 67 | self::writeLogs($config, "FUNCTION:" . $setLogFunction); 68 | self::writeLogs($config, "URL:" . $url); 69 | self::writeLogs($config, "REQUEST:", $logRequest); 70 | self::writeLogs($config, "RESPONSE:", $logResponse . "\r\n"); 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * Duitku write log parameter for callback only 77 | * 78 | * Please set => 79 | * $duitkuConfig = new \Duitku\Config(); 80 | * $duitkuConfig->setDuitkuLogs(true); // default true 81 | * 82 | */ 83 | protected static function writeDuitkuLogsCallback($url, $logRequest, $config) 84 | { 85 | if ($config->getDuitkuLogs()) { 86 | if (!empty($logRequest)) { 87 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 88 | self::writeLogs($config, "URL:" . $url); 89 | self::writeLogs($config, "CALLBACK REQUEST:", $logRequest . "\r\n"); 90 | } 91 | } 92 | } 93 | 94 | /** 95 | * Write Log parameter 96 | * 97 | */ 98 | private static function writeLogs($config, $logTitle, $logMessage = '') 99 | { 100 | $rootDirLogs = __DIR__ . "/../logs/"; 101 | 102 | // create dir logs 103 | if (!is_dir($rootDirLogs)) 104 | mkdir($rootDirLogs); 105 | 106 | file_put_contents($rootDirLogs . $config->getLogFileName(), $logTitle . stripslashes($logMessage) . "\r\n", FILE_APPEND | LOCK_EX); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /example/env/Duitku/Sanitizer.php: -------------------------------------------------------------------------------- 1 | "int|maxLength:50", 17 | "merchantOrderId" => "string|maxLength:50", 18 | "productDetails" => "string|maxLength:255", 19 | "additionalParam" => "string|maxLength:255", 20 | "merchantUserInfo" => "string|maxLength:255", 21 | "customerVaName" => "string|maxLength:20", 22 | "phoneNumber" => "string|maxLength:20|phone", 23 | "expiryPeriod" => "int", 24 | 25 | // itemDetails 26 | "name" => "string|maxLength:50", 27 | "quantity" => "int", 28 | "price" => "int", 29 | 30 | //billingAddress and shippingAddress 31 | 'firstName' => "string|maxLength:50", 32 | 'lastName' => "string|maxLength:50", 33 | 'address' => "string|maxLength:255", 34 | 'city' => "string|maxLength:50", 35 | 'postalCode' => "string|maxLength:50", 36 | 'phone' => "string|maxLength:20|phone", 37 | 'countryCode' => "string|maxLength:50" 38 | ); 39 | 40 | /** 41 | * 42 | * Example: 43 | * 44 | * ```php 45 | * 46 | * $params = array( 47 | * "example1" => "value1", 48 | * "example2" => "value2", 49 | * "example3" => "value3", 50 | * ); 51 | * 52 | * \Duitku\Sanitizer::request($params); 53 | * 54 | * ``` 55 | * 56 | * @param array &$parameterArray 57 | * @return void 58 | */ 59 | public static function Request(&$parameterArray) 60 | { 61 | if (!is_array($parameterArray)) { 62 | return; 63 | } 64 | 65 | foreach ($parameterArray as $rulesLabel => &$parameterValue) { 66 | if (is_array($parameterValue)) { 67 | // parse itemDetails and customerDetail 68 | foreach ($parameterValue as $rulesCustomerDetail => &$parameterCustomerDetail) { 69 | // parse billingAddress and shippingAddress 70 | self::loopParamAddress($parameterCustomerDetail); 71 | 72 | if (isset(self::$_rules[$rulesCustomerDetail])) { 73 | self::sanitizeValue(self::$_rules[$rulesCustomerDetail], $parameterCustomerDetail); 74 | } 75 | } 76 | } 77 | 78 | if (isset(self::$_rules[$rulesLabel])) { 79 | self::sanitizeValue(self::$_rules[$rulesLabel], $parameterValue); 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * Filter field "int|string|maxLength|phone" 86 | * 87 | * @param string $fieldName 88 | * @param string &$parameterValue 89 | * @return void 90 | */ 91 | private static function sanitizeValue($fieldName, &$parameterValue) 92 | { 93 | $attributeTags = explode('|', $fieldName); 94 | rsort($attributeTags); 95 | foreach ($attributeTags as $attributeTag) { 96 | $attributeTagValue = explode(':', $attributeTag); 97 | switch ($attributeTagValue[0]) { 98 | case "string": 99 | $parameterValue = (string)$parameterValue; 100 | break; 101 | case "int": 102 | $parameterValue = (int)$parameterValue; 103 | break; 104 | case "maxLength": 105 | $parameterValue = substr($parameterValue, 0, $attributeTagValue[1]); 106 | break; 107 | case "phone": 108 | $parameterValue = preg_replace("/[^\\d\\-\\(\\)]/", '', $parameterValue); 109 | break; 110 | } 111 | } 112 | } 113 | 114 | /** 115 | * Parse billingAddress and shippingAddress 116 | * 117 | * @param array &$parameterCustomerDetail 118 | * @return void 119 | */ 120 | private static function loopParamAddress(&$parameterCustomerDetail) 121 | { 122 | if (!is_array($parameterCustomerDetail)) { 123 | return; 124 | } 125 | 126 | foreach ($parameterCustomerDetail as $rulesAddress => &$parameterAddress) { 127 | self::sanitizeValue(self::$_rules[$rulesAddress], $parameterAddress); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /example/env/GetPaymentMethod-Api.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 24 | $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $duitkuConfig); 25 | 26 | header('Content-Type: application/json'); 27 | echo $paymentMethodList; 28 | } catch (Exception $e) { 29 | echo $e->getMessage(); 30 | } 31 | -------------------------------------------------------------------------------- /example/env/GetPaymentMethod.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 24 | $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $duitkuConfig); 25 | 26 | header('Content-Type: application/json'); 27 | echo $paymentMethodList; 28 | } catch (Exception $e) { 29 | echo $e->getMessage(); 30 | } 31 | -------------------------------------------------------------------------------- /example/env/PhpDotEnv/DotEnv.php: -------------------------------------------------------------------------------- 1 | path = $path; 22 | } 23 | 24 | public function load(): void 25 | { 26 | if (!is_readable($this->path)) { 27 | throw new \RuntimeException(sprintf('%s file is not readable', $this->path)); 28 | } 29 | 30 | $lines = file($this->path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 31 | foreach ($lines as $line) { 32 | 33 | if (strpos(trim($line), '#') === 0) { 34 | continue; 35 | } 36 | 37 | list($name, $value) = explode('=', $line, 2); 38 | $name = trim($name); 39 | $value = trim($value); 40 | 41 | if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) { 42 | putenv(sprintf('%s=%s', $name, $value)); 43 | $_ENV[$name] = $value; 44 | $_SERVER[$name] = $value; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /example/env/TransactionStatus-Api.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 24 | $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $duitkuConfig); 25 | 26 | header('Content-Type: application/json'); 27 | $transaction = json_decode($transactionList); 28 | 29 | // var_dump($transactionList); 30 | 31 | if ($transaction->statusCode == "00") { 32 | // Action Success 33 | } else if ($transaction->statusCode == "01") { 34 | // Action Pending 35 | } else { 36 | // Action Failed Or Expired 37 | } 38 | } catch (Exception $e) { 39 | echo $e->getMessage(); 40 | } 41 | -------------------------------------------------------------------------------- /example/env/TransactionStatus.php: -------------------------------------------------------------------------------- 1 | load(); 9 | 10 | $duitkuConfig = new \Duitku\Config(getenv("SANDBOX_KEY"), getenv("SANDBOX_MERCHANTCODE")); 11 | 12 | if (getenv("SANDBOX_MODE") == "true") { 13 | $duitkuConfig->setApiKey(getenv("SANDBOX_KEY")); //'YOUR_MERCHANT_KEY'; 14 | $duitkuConfig->setMerchantCode(getenv("SANDBOX_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 15 | $duitkuConfig->setSandboxMode(true); 16 | } else { 17 | $duitkuConfig->setApiKey(getenv("PRODUCTION_KEY")); //'YOUR_MERCHANT_KEY'; 18 | $duitkuConfig->setMerchantCode(getenv("PRODUCTION_MERCHANTCODE")); //'YOUR_MERCHANT_CODE'; 19 | $duitkuConfig->setSandboxMode(false); 20 | } 21 | 22 | try { 23 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 24 | $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $duitkuConfig); 25 | 26 | header('Content-Type: application/json'); 27 | $transaction = json_decode($transactionList); 28 | 29 | // var_dump($transactionList); 30 | 31 | if ($transaction->statusCode == "00") { 32 | // Action Success 33 | } else if ($transaction->statusCode == "01") { 34 | // Action Pending 35 | } else { 36 | // Action Failed Or Expired 37 | } 38 | } catch (Exception $e) { 39 | echo $e->getMessage(); 40 | } 41 | -------------------------------------------------------------------------------- /example/non-composer/Callback-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $callback = \Duitku\Api::callback($duitkuConfig); 11 | 12 | header('Content-Type: application/json'); 13 | $notif = json_decode($callback); 14 | 15 | // var_dump($callback); 16 | 17 | if ($notif->resultCode == "00") { 18 | // Action Success 19 | } else if ($notif->resultCode == "01") { 20 | // Action Failed 21 | } 22 | } catch (Exception $e) { 23 | http_response_code(400); 24 | echo $e->getMessage(); 25 | } 26 | -------------------------------------------------------------------------------- /example/non-composer/Callback.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $callback = \Duitku\Pop::callback($duitkuConfig); 11 | 12 | header('Content-Type: application/json'); 13 | $notif = json_decode($callback); 14 | 15 | // var_dump($callback); 16 | 17 | if ($notif->resultCode == "00") { 18 | // Action Success 19 | } else if ($notif->resultCode == "01") { 20 | // Action Failed 21 | } 22 | } catch (Exception $e) { 23 | http_response_code(400); 24 | echo $e->getMessage(); 25 | } 26 | -------------------------------------------------------------------------------- /example/non-composer/CreateInvoice-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | $paymentAmount = 10000; // Amount 10 | $paymentMethod = "BT"; // Permata Bank Virtual Account 11 | $email = "customer@gmail.com"; // your customer email 12 | $phoneNumber = "081234567890"; // your customer phone number (optional) 13 | $productDetails = "Test Payment"; 14 | $merchantOrderId = time(); // from merchant, unique 15 | $additionalParam = ''; // optional 16 | $merchantUserInfo = ''; // optional 17 | $customerVaName = 'John Doe'; // display name on bank confirmation display 18 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 19 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 20 | $expiryPeriod = 60; // set the expired time in minutes 21 | 22 | // Customer Detail 23 | $firstName = "John"; 24 | $lastName = "Doe"; 25 | 26 | // Address 27 | $alamat = "Jl. Kembangan Raya"; 28 | $city = "Jakarta"; 29 | $postalCode = "11530"; 30 | $countryCode = "ID"; 31 | 32 | $address = array( 33 | 'firstName' => $firstName, 34 | 'lastName' => $lastName, 35 | 'address' => $alamat, 36 | 'city' => $city, 37 | 'postalCode' => $postalCode, 38 | 'phone' => $phoneNumber, 39 | 'countryCode' => $countryCode 40 | ); 41 | 42 | $customerDetail = array( 43 | 'firstName' => $firstName, 44 | 'lastName' => $lastName, 45 | 'email' => $email, 46 | 'phoneNumber' => $phoneNumber, 47 | 'billingAddress' => $address, 48 | 'shippingAddress' => $address 49 | ); 50 | 51 | 52 | // Item Details 53 | $item1 = array( 54 | 'name' => $productDetails, 55 | 'price' => $paymentAmount, 56 | 'quantity' => 1 57 | ); 58 | 59 | 60 | $itemDetails = array( 61 | $item1 62 | ); 63 | 64 | $params = array( 65 | 'paymentAmount' => $paymentAmount, 66 | 'paymentMethod' => $paymentMethod, 67 | 'merchantOrderId' => $merchantOrderId, 68 | 'productDetails' => $productDetails, 69 | 'additionalParam' => $additionalParam, 70 | 'merchantUserInfo' => $merchantUserInfo, 71 | 'customerVaName' => $customerVaName, 72 | 'email' => $email, 73 | 'phoneNumber' => $phoneNumber, 74 | 'itemDetails' => $itemDetails, 75 | 'customerDetail' => $customerDetail, 76 | 'callbackUrl' => $callbackUrl, 77 | 'returnUrl' => $returnUrl, 78 | 'expiryPeriod' => $expiryPeriod 79 | ); 80 | 81 | try { 82 | // createInvoice Request 83 | $responseDuitkuApi = \Duitku\Api::createInvoice($params, $duitkuConfig); 84 | 85 | header('Content-Type: application/json'); 86 | 87 | $responseDuitku = json_decode($responseDuitkuApi); 88 | 89 | // var_dump($$responseDuitku); 90 | 91 | if ($responseDuitku->statusCode == "00") { 92 | header('location: ' . $responseDuitku->paymentUrl); 93 | } 94 | } catch (Exception $e) { 95 | echo $e->getMessage(); 96 | } 97 | -------------------------------------------------------------------------------- /example/non-composer/CreateInvoice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 23 |
24 | 25 |
26 |

Duitku Pop

27 |
28 |
29 | 30 |
31 | 32 | 34 |
35 | 36 |
37 | 38 | 40 |
41 | 42 |
43 | 44 | 46 |
47 | 48 |
49 | 50 | 52 |
53 | 54 |
55 | 56 | 60 |
61 | 62 | 64 | 65 |
66 | 67 |
68 |
69 | 70 | 71 | 72 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /example/non-composer/CreateInvoice.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | // Parameter PaymentMethod is optional 10 | // $paymentMethod = ""; // PaymentMethod list => https://docs.duitku.com/pop/id/#payment-method 11 | $paymentAmount = 10000; // Amount 12 | $email = "customer@gmail.com"; // your customer email 13 | $phoneNumber = "081234567890"; // your customer phone number (optional) 14 | $productDetails = "Test Payment"; 15 | $merchantOrderId = time(); // from merchant, unique 16 | $additionalParam = ''; // optional 17 | $merchantUserInfo = ''; // optional 18 | $customerVaName = 'John Doe'; // display name on bank confirmation display 19 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 20 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 21 | $expiryPeriod = 60; // set the expired time in minutes 22 | 23 | // Customer Detail 24 | $firstName = "John"; 25 | $lastName = "Doe"; 26 | 27 | // Address 28 | $alamat = "Jl. Kembangan Raya"; 29 | $city = "Jakarta"; 30 | $postalCode = "11530"; 31 | $countryCode = "ID"; 32 | 33 | $address = array( 34 | 'firstName' => $firstName, 35 | 'lastName' => $lastName, 36 | 'address' => $alamat, 37 | 'city' => $city, 38 | 'postalCode' => $postalCode, 39 | 'phone' => $phoneNumber, 40 | 'countryCode' => $countryCode 41 | ); 42 | 43 | $customerDetail = array( 44 | 'firstName' => $firstName, 45 | 'lastName' => $lastName, 46 | 'email' => $email, 47 | 'phoneNumber' => $phoneNumber, 48 | 'billingAddress' => $address, 49 | 'shippingAddress' => $address 50 | ); 51 | 52 | 53 | // Item Details 54 | $item1 = array( 55 | 'name' => $productDetails, 56 | 'price' => $paymentAmount, 57 | 'quantity' => 1 58 | ); 59 | 60 | 61 | $itemDetails = array( 62 | $item1 63 | ); 64 | 65 | $params = array( 66 | 'paymentAmount' => $paymentAmount, 67 | 'merchantOrderId' => $merchantOrderId, 68 | 'productDetails' => $productDetails, 69 | 'additionalParam' => $additionalParam, 70 | 'merchantUserInfo' => $merchantUserInfo, 71 | 'customerVaName' => $customerVaName, 72 | 'email' => $email, 73 | 'phoneNumber' => $phoneNumber, 74 | 'itemDetails' => $itemDetails, 75 | 'customerDetail' => $customerDetail, 76 | 'callbackUrl' => $callbackUrl, 77 | 'returnUrl' => $returnUrl, 78 | 'expiryPeriod' => $expiryPeriod 79 | ); 80 | 81 | try { 82 | // createInvoice Request 83 | $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $duitkuConfig); 84 | 85 | header('Content-Type: application/json'); 86 | echo $responseDuitkuPop; 87 | } catch (Exception $e) { 88 | echo $e->getMessage(); 89 | } 90 | -------------------------------------------------------------------------------- /example/non-composer/Duitku.php: -------------------------------------------------------------------------------- 1 | = 5.6 required'); 8 | } 9 | 10 | // Check PHP Curl & 11 | if (!function_exists('curl_init') || !function_exists('curl_exec')) { 12 | throw new Exception('Duitku::cURL library is required'); 13 | } 14 | 15 | // Json decode capabilities. 16 | if (!function_exists('json_decode')) { 17 | throw new Exception('Duitku::JSON PHP extension is required'); 18 | } 19 | 20 | // Configuration Duitku Config 21 | require_once 'lib/Config.php'; 22 | // Duitku Sanitizer Parameter 23 | require_once 'lib/Sanitizer.php'; 24 | // Duitku Request Curl 25 | require_once 'lib/Request.php'; 26 | // General Duitku-Pop Request 27 | require_once 'lib/Pop.php'; 28 | // General Duitku-API Request 29 | require_once 'lib/Api.php'; 30 | -------------------------------------------------------------------------------- /example/non-composer/GetPaymentMethod-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 11 | $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | echo $paymentMethodList; 15 | } catch (Exception $e) { 16 | echo $e->getMessage(); 17 | } 18 | -------------------------------------------------------------------------------- /example/non-composer/GetPaymentMethod.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 11 | $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | echo $paymentMethodList; 15 | } catch (Exception $e) { 16 | echo $e->getMessage(); 17 | } 18 | -------------------------------------------------------------------------------- /example/non-composer/TransactionStatus-Api.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 11 | $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | $transaction = json_decode($transactionList); 15 | 16 | // var_dump($transactionList); 17 | 18 | if ($transaction->statusCode == "00") { 19 | // Action Success 20 | } else if ($transaction->statusCode == "01") { 21 | // Action Pending 22 | } else { 23 | // Action Failed Or Expired 24 | } 25 | } catch (Exception $e) { 26 | echo $e->getMessage(); 27 | } 28 | -------------------------------------------------------------------------------- /example/non-composer/TransactionStatus.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 7 | // $duitkuConfig->setDuitkuLogs(false); 8 | 9 | try { 10 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 11 | $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $duitkuConfig); 12 | 13 | header('Content-Type: application/json'); 14 | $transaction = json_decode($transactionList); 15 | 16 | // var_dump($transactionList); 17 | 18 | if ($transaction->statusCode == "00") { 19 | // Action Success 20 | } else if ($transaction->statusCode == "01") { 21 | // Action Pending 22 | } else { 23 | // Action Failed Or Expired 24 | } 25 | } catch (Exception $e) { 26 | echo $e->getMessage(); 27 | } 28 | -------------------------------------------------------------------------------- /example/non-composer/lib/Api.php: -------------------------------------------------------------------------------- 1 | $firstName, 43 | * 'lastName' => $lastName, 44 | * 'address' => $alamat, 45 | * 'city' => $city, 46 | * 'postalCode' => $postalCode, 47 | * 'phone' => $phoneNumber, 48 | * 'countryCode' => $countryCode 49 | * ); 50 | * 51 | * $customerDetail = array( 52 | * 'firstName' => $firstName, 53 | * 'lastName' => $lastName, 54 | * 'email' => $email, 55 | * 'phoneNumber' => $phoneNumber, 56 | * 'billingAddress' => $address, 57 | * 'shippingAddress' => $address 58 | * ); 59 | * 60 | * // Item Details 61 | * $item1 = array( 62 | * 'name' => $productDetails, 63 | * 'price' => $paymentAmount, 64 | * 'quantity' => 1 65 | * ); 66 | * 67 | * $itemDetails = array( 68 | * $item1 69 | * ); 70 | * 71 | * $params = array( 72 | * 'paymentAmount' => $paymentAmount, 73 | * 'paymentMethod' => $paymentMethod, 74 | * 'merchantOrderId' => $merchantOrderId, 75 | * 'productDetails' => $productDetails, 76 | * 'additionalParam' => $additionalParam, 77 | * 'merchantUserInfo' => $merchantUserInfo, 78 | * 'customerVaName' => $customerVaName, 79 | * 'email' => $email, 80 | * 'phoneNumber' => $phoneNumber, 81 | * 'itemDetails' => $itemDetails, 82 | * 'customerDetail' => $customerDetail, 83 | * 'callbackUrl' => $callbackUrl, 84 | * 'returnUrl' => $returnUrl, 85 | * 'expiryPeriod' => $expiryPeriod 86 | * ); 87 | * 88 | * try { 89 | * // createInvoice Request 90 | * $responseDuitkuApi = \Duitku\Api::createInvoice($params, $config); 91 | * 92 | * header('Content-Type: application/json'); 93 | * echo $responseDuitkuApi; 94 | * } catch (Exception $e) { 95 | * echo $e->getMessage(); 96 | * } 97 | * 98 | * ``` 99 | * @param array $payload 100 | * @param \Duitku\Config $config 101 | * @return string response duitku API. 102 | * @throws Exception 103 | */ 104 | public static function createInvoice($payload, $config) 105 | { 106 | if ($config->getSanitizedMode()) { 107 | \Duitku\Sanitizer::request($payload); 108 | } 109 | 110 | $timestamp = round(microtime(true) * 1000); 111 | $payload["merchantCode"] = $config->getMerchantCode(); 112 | $payload["signature"] = md5($config->getMerchantCode() . $payload["merchantOrderId"] . $payload["paymentAmount"] . $config->getApiKey()); 113 | 114 | $params = json_encode($payload); 115 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 116 | $url = $config->getApiUrl() . '/webapi/api/merchant/v2/inquiry'; 117 | return self::sendRequest($url, $params, $config, $setLogFunction); 118 | } 119 | 120 | /** 121 | * Cek Transaction Duitku API 122 | * 123 | * Example: 124 | * 125 | * ```php 126 | * 127 | * try { 128 | * $merchantOrderId = "YOUR_ORDER_ID"; 129 | * $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $config); 130 | * 131 | * header('Content-Type: application/json'); 132 | * echo json_encode($transactionList); 133 | * 134 | * if ($transaction->statusCode == "00") { 135 | * // Action Success 136 | * } else if ($transaction->statusCode == "01") { 137 | * // Action Pending 138 | * } else { 139 | * // Action Failed Or Expired 140 | * } 141 | * } 142 | * catch (Exception $e) { 143 | * echo $e->getMessage(); 144 | * } 145 | * ``` 146 | * 147 | * @param string $merchantOrderId 148 | * @param \Duitku\Config $config 149 | * @return string response cek status duitku API. 150 | * @throws Exception 151 | */ 152 | public static function transactionStatus($merchantOrderId, $config) 153 | { 154 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 155 | 156 | $payload = array( 157 | 'merchantCode' => $config->getMerchantCode(), 158 | 'merchantOrderId' => $merchantOrderId, 159 | 'signature' => $signature 160 | ); 161 | 162 | $params = json_encode($payload); 163 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 164 | $url = $config->getApiUrl() . '/webapi/api/merchant/transactionStatus'; 165 | return self::sendRequest($url, $params, $config, $setLogFunction); 166 | } 167 | 168 | /** 169 | * Get List Payment Method Duitku API 170 | * 171 | * Example: 172 | * 173 | * ```php 174 | * 175 | * try { 176 | * $paymentAmount = 10000; 177 | * $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $config); 178 | * 179 | * var_dump(paymentMethodList) 180 | * 181 | * } 182 | * catch (Exception $e) { 183 | * echo $e->getMessage(); 184 | * } 185 | * ``` 186 | * 187 | * @param \Duitku\Config $config 188 | * @return string response cek status duitku API. 189 | * @throws Exception 190 | */ 191 | public static function getPaymentMethod($paymentAmount, $config) 192 | { 193 | $datetime = date('Y-m-d H:i:s'); 194 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 195 | 196 | $payload = array( 197 | 'merchantCode' => $config->getMerchantCode(), 198 | 'amount' => $paymentAmount, 199 | 'datetime' => $datetime, 200 | 'signature' => $signature 201 | ); 202 | 203 | $params = json_encode($payload); 204 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 205 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 206 | return self::sendRequest($url, $params, $config, $setLogFunction); 207 | } 208 | 209 | /** 210 | * Callback Duitku API 211 | * Handle Method HTTP POST => Type x-www-form-urlencoded 212 | * 213 | * Example 214 | * 215 | * try { 216 | * $callback = \Duitku\Api::callback($config); 217 | * 218 | * header('Content-Type: application/json'); 219 | * $notif = json_decode($callback); 220 | * 221 | * if ($notif->resultCode == "00") { 222 | * // Action Success 223 | * } else if ($notif->resultCode == "01") { 224 | * // Action Pending 225 | * } else { 226 | * // Ignore 227 | * } 228 | * 229 | * } catch (Exception $e) { 230 | * http_response_code(400); 231 | * echo $e->getMessage(); 232 | * } 233 | * 234 | * @param \Duitku\Config $config 235 | * @return json response 236 | * @throws Exception 237 | */ 238 | public static function callback($config) 239 | { 240 | $notification = $_POST; 241 | if (empty($notification)) { 242 | throw new \Exception('Access denied'); 243 | } 244 | 245 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 246 | 247 | foreach ($config->callbackParams as $callbackParam) { 248 | if (!array_key_exists($callbackParam, $notification)) { 249 | $notification[$callbackParam] = null; 250 | } 251 | } 252 | 253 | if (!self::isSignatureValid($notification, $config)) { 254 | throw new \Exception('Signature Invalid'); 255 | } 256 | 257 | return json_encode($notification); 258 | } 259 | 260 | /** 261 | * Validation signature callback duitku API 262 | * 263 | */ 264 | private static function isSignatureValid($notification, $config) 265 | { 266 | $signature = $notification['signature']; 267 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 268 | return $signature == $signGenerate; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /example/non-composer/lib/Config.php: -------------------------------------------------------------------------------- 1 | _apiKey = $apiKey; 22 | $this->_merchantCode = $merchantCode; 23 | $this->_isSandboxMode = $isSandboxMode; 24 | $this->_isSanitizedMode = $isSanitizedMode; 25 | $this->_duitkuLogs = $duitkuLogs; 26 | } 27 | 28 | /** 29 | * Your merchant's api key 30 | * 31 | */ 32 | private $_apiKey; 33 | /** 34 | * Your merchant's merchant code 35 | * 36 | */ 37 | private $_merchantCode; 38 | /** 39 | * false for production 40 | * true for sandbox 41 | * 42 | */ 43 | private $_isSandboxMode; 44 | /** 45 | * Enable request params sanitized mode / default true 46 | * 47 | */ 48 | private $_isSanitizedMode; 49 | /** 50 | * Set it true to enable log file 51 | * 52 | */ 53 | private $_duitkuLogs; 54 | 55 | /** 56 | * Set Callback Parameter 57 | * 58 | */ 59 | public $callbackParams = array( 60 | "merchantCode", 61 | "amount", 62 | "merchantOrderId", 63 | "productDetail", 64 | "additionalParam", 65 | "paymentCode", 66 | "resultCode", 67 | "merchantUserId", 68 | "reference", 69 | "signature", 70 | "spUserHash" 71 | ); 72 | 73 | const SANDBOX_URL = 'https://api-sandbox.duitku.com'; 74 | const PASSPORT_URL = 'https://api-prod.duitku.com'; 75 | 76 | const SANDBOX_API_URL = 'https://sandbox.duitku.com'; 77 | const PASSPORT_API_URL = 'https://passport.duitku.com'; 78 | 79 | /** 80 | * Set apiKey config 81 | * 82 | */ 83 | public function setApiKey($apiKey) 84 | { 85 | $this->_apiKey = $apiKey; 86 | } 87 | 88 | /** 89 | * Get apiKey config 90 | * 91 | */ 92 | public function getApiKey() 93 | { 94 | return $this->_apiKey; 95 | } 96 | 97 | /** 98 | * Set merchantCode config 99 | * 100 | */ 101 | public function setMerchantCode($merchantCode) 102 | { 103 | $this->_merchantCode = $merchantCode; 104 | } 105 | 106 | /** 107 | * Get merchantCode config 108 | * 109 | */ 110 | public function getMerchantCode() 111 | { 112 | return $this->_merchantCode; 113 | } 114 | 115 | /** 116 | * Set sandboxMode config 117 | * 118 | */ 119 | public function setSandboxMode($isSandboxMode) 120 | { 121 | $this->_isSandboxMode = $isSandboxMode; 122 | } 123 | 124 | /** 125 | * Get sandboxMode config 126 | * 127 | */ 128 | public function getSandboxMode() 129 | { 130 | return $this->_isSandboxMode; 131 | } 132 | 133 | /** 134 | * Set sanitizedMode config 135 | * 136 | */ 137 | public function setSanitizedMode($isSanitizedMode) 138 | { 139 | $this->_isSanitizedMode = $isSanitizedMode; 140 | } 141 | 142 | /** 143 | * Get sanitizedMode config 144 | * 145 | */ 146 | public function getSanitizedMode() 147 | { 148 | return $this->_isSanitizedMode; 149 | } 150 | 151 | /** 152 | * Set duitkuLogs config 153 | * 154 | */ 155 | public function setDuitkuLogs($duitkuLogs) 156 | { 157 | $this->_duitkuLogs = $duitkuLogs; 158 | } 159 | 160 | /** 161 | * Get duitkuLogs config 162 | * 163 | */ 164 | public function getDuitkuLogs() 165 | { 166 | return $this->_duitkuLogs; 167 | } 168 | 169 | /** 170 | * Get apiUrl 171 | * 172 | * @return Duitku API URL, depends on $_isSandboxMode 173 | */ 174 | public function getApiUrl() 175 | { 176 | if ($this->getSandboxMode()) { 177 | return self::SANDBOX_API_URL; 178 | } else { 179 | return self::PASSPORT_API_URL; 180 | } 181 | } 182 | 183 | /** 184 | * Get baseUrl 185 | * 186 | * @return Duitku POP URL, depends on $_isSandboxMode 187 | */ 188 | public function getBaseUrl() 189 | { 190 | if ($this->getSandboxMode()) { 191 | return self::SANDBOX_URL; 192 | } else { 193 | return self::PASSPORT_URL; 194 | } 195 | } 196 | 197 | /** 198 | * Generate string log file name 199 | * 200 | * @return string 201 | */ 202 | public function getLogFileName() 203 | { 204 | $logFileName = "duitku_" . date('Ymd') . ".log"; 205 | return $logFileName; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /example/non-composer/lib/Pop.php: -------------------------------------------------------------------------------- 1 | $firstName, 42 | * 'lastName' => $lastName, 43 | * 'address' => $alamat, 44 | * 'city' => $city, 45 | * 'postalCode' => $postalCode, 46 | * 'phone' => $phoneNumber, 47 | * 'countryCode' => $countryCode 48 | * ); 49 | * 50 | * $customerDetail = array( 51 | * 'firstName' => $firstName, 52 | * 'lastName' => $lastName, 53 | * 'email' => $email, 54 | * 'phoneNumber' => $phoneNumber, 55 | * 'billingAddress' => $address, 56 | * 'shippingAddress' => $address 57 | * ); 58 | * 59 | * // Item Details 60 | * $item1 = array( 61 | * 'name' => $productDetails, 62 | * 'price' => $paymentAmount, 63 | * 'quantity' => 1 64 | * ); 65 | * 66 | * $itemDetails = array( 67 | * $item1 68 | * ); 69 | * 70 | * $params = array( 71 | * 'paymentAmount' => $paymentAmount, 72 | * 'merchantOrderId' => $merchantOrderId, 73 | * 'productDetails' => $productDetails, 74 | * 'additionalParam' => $additionalParam, 75 | * 'merchantUserInfo' => $merchantUserInfo, 76 | * 'customerVaName' => $customerVaName, 77 | * 'email' => $email, 78 | * 'phoneNumber' => $phoneNumber, 79 | * 'itemDetails' => $itemDetails, 80 | * 'customerDetail' => $customerDetail, 81 | * 'callbackUrl' => $callbackUrl, 82 | * 'returnUrl' => $returnUrl, 83 | * 'expiryPeriod' => $expiryPeriod 84 | * ); 85 | * 86 | * try { 87 | * // createInvoice Request 88 | * $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $config); 89 | * 90 | * header('Content-Type: application/json'); 91 | * echo $responseDuitkuPop; 92 | * } catch (Exception $e) { 93 | * echo $e->getMessage(); 94 | * } 95 | * 96 | * ``` 97 | * @param array $payload 98 | * @param \Duitku\Config $config 99 | * @return string response duitku pop. 100 | * @throws Exception 101 | */ 102 | public static function createInvoice($payload, $config) 103 | { 104 | if ($config->getSanitizedMode()) { 105 | \Duitku\Sanitizer::request($payload); 106 | } 107 | 108 | $timestamp = round(microtime(true) * 1000); 109 | $signature = hash('sha256', $config->getMerchantCode() . $timestamp . $config->getApiKey()); 110 | 111 | $params = json_encode($payload); 112 | $header = array( 113 | 'x-duitku-signature:' . $signature, 114 | 'x-duitku-timestamp:' . $timestamp, 115 | 'x-duitku-merchantcode:' . $config->getMerchantCode() 116 | ); 117 | 118 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 119 | $url = $config->getBaseUrl() . '/api/merchant/createInvoice'; 120 | return self::sendRequest($url, $params, $config, $setLogFunction, $header); 121 | } 122 | 123 | /** 124 | * Cek Transaction Duitku Pop 125 | * 126 | * Example: 127 | * 128 | * ```php 129 | * 130 | * try { 131 | * $merchantOrderId = "YOUR_ORDER_ID"; 132 | * $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $config); 133 | * 134 | * header('Content-Type: application/json'); 135 | * echo json_encode($transactionList); 136 | * 137 | * if ($transaction->statusCode == "00") { 138 | * // Action Success 139 | * } else if ($transaction->statusCode == "01") { 140 | * // Action Pending 141 | * } else { 142 | * // Action Failed Or Expired 143 | * } 144 | * } 145 | * catch (Exception $e) { 146 | * echo $e->getMessage(); 147 | * } 148 | * ``` 149 | * 150 | * @param string $merchantOrderId 151 | * @param \Duitku\Config $config 152 | * @return string response cek status duitku pop. 153 | * @throws Exception 154 | */ 155 | public static function transactionStatus($merchantOrderId, $config) 156 | { 157 | $signature = md5($config->getMerchantCode() . $merchantOrderId . $config->getApiKey()); 158 | 159 | $payload = array( 160 | 'merchantCode' => $config->getMerchantCode(), 161 | 'merchantOrderId' => $merchantOrderId, 162 | 'signature' => $signature 163 | ); 164 | 165 | $params = json_encode($payload); 166 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 167 | $url = $config->getBaseUrl() . '/api/merchant/transactionStatus'; 168 | return self::sendRequest($url, $params, $config, $setLogFunction); 169 | } 170 | 171 | /** 172 | * Get List Payment Method Duitku Pop 173 | * 174 | * Example: 175 | * 176 | * ```php 177 | * 178 | * try { 179 | * $paymentAmount = 10000; 180 | * $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $config); 181 | * 182 | * var_dump(paymentMethodList) 183 | * 184 | * } 185 | * catch (Exception $e) { 186 | * echo $e->getMessage(); 187 | * } 188 | * ``` 189 | * 190 | * @param \Duitku\Config $config 191 | * @return string response cek status duitku Pop. 192 | * @throws Exception 193 | */ 194 | public static function getPaymentMethod($paymentAmount, $config) 195 | { 196 | $datetime = date('Y-m-d H:i:s'); 197 | $signature = hash("sha256", $config->getMerchantCode() . $paymentAmount . $datetime . $config->getApiKey()); 198 | 199 | $payload = array( 200 | 'merchantCode' => $config->getMerchantCode(), 201 | 'amount' => $paymentAmount, 202 | 'datetime' => $datetime, 203 | 'signature' => $signature 204 | ); 205 | 206 | $params = json_encode($payload); 207 | $setLogFunction = __CLASS__ . "->" . __FUNCTION__; 208 | 209 | // endpoint url api v2 210 | $url = $config->getApiUrl() . '/webapi/api/merchant/paymentmethod/getpaymentmethod'; 211 | return self::sendRequest($url, $params, $config, $setLogFunction); 212 | } 213 | 214 | /** 215 | * Callback Duitku Pop 216 | * Handle Method HTTP POST => Type x-www-form-urlencoded 217 | * 218 | * Example 219 | * 220 | * try { 221 | * $callback = \Duitku\Pop::callback($config); 222 | * 223 | * header('Content-Type: application/json'); 224 | * $notif = json_decode($callback); 225 | * 226 | * if ($notif->resultCode == "00") { 227 | * // Action Success 228 | * } else if ($notif->resultCode == "01") { 229 | * // Action Pending 230 | * } else { 231 | * // Ignore 232 | * } 233 | * 234 | * } catch (Exception $e) { 235 | * http_response_code(400); 236 | * echo $e->getMessage(); 237 | * } 238 | * 239 | * @param \Duitku\Config $config 240 | * @return json response 241 | * @throws Exception 242 | */ 243 | public static function callback($config) 244 | { 245 | $notification = $_POST; 246 | if (empty($notification)) { 247 | throw new \Exception('Access denied'); 248 | } 249 | 250 | self::writeDuitkuLogsCallback($_SERVER['PHP_SELF'], json_encode($notification), $config); 251 | 252 | foreach ($config->callbackParams as $callbackParam) { 253 | if (!array_key_exists($callbackParam, $notification)) { 254 | $notification[$callbackParam] = null; 255 | } 256 | } 257 | 258 | if (!self::isSignatureValid($notification, $config)) { 259 | throw new \Exception('Signature Invalid'); 260 | } 261 | 262 | return json_encode($notification); 263 | } 264 | 265 | /** 266 | * Validation signature callback duitku pop 267 | * 268 | */ 269 | private static function isSignatureValid($notification, $config) 270 | { 271 | $signature = $notification['signature']; 272 | $signGenerate = md5($notification['merchantCode'] . $notification['amount'] . $notification['merchantOrderId'] . $config->getApiKey()); 273 | return $signature == $signGenerate; 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /example/non-composer/lib/Request.php: -------------------------------------------------------------------------------- 1 | = 400) { 47 | throw new \Exception('Duitku Error: ' . $httpCode . ' response: ' . $response); 48 | } else { 49 | return $response; 50 | } 51 | } 52 | 53 | /** 54 | * Duitku write log parameter 55 | * 56 | * Please set => 57 | * $duitkuConfig = new \Duitku\Config(); 58 | * $duitkuConfig->setDuitkuLogs(true); // default true 59 | * 60 | */ 61 | protected static function writeDuitkuLogs($setLogFunction, $url, $method, $logRequest, $logResponse, $config) 62 | { 63 | if ($config->getDuitkuLogs()) { 64 | if (!empty($logRequest)) { 65 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 66 | self::writeLogs($config, "METHOD:" . $method); 67 | self::writeLogs($config, "FUNCTION:" . $setLogFunction); 68 | self::writeLogs($config, "URL:" . $url); 69 | self::writeLogs($config, "REQUEST:", $logRequest); 70 | self::writeLogs($config, "RESPONSE:", $logResponse . "\r\n"); 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * Duitku write log parameter for callback only 77 | * 78 | * Please set => 79 | * $duitkuConfig = new \Duitku\Config(); 80 | * $duitkuConfig->setDuitkuLogs(true); // default true 81 | * 82 | */ 83 | protected static function writeDuitkuLogsCallback($url, $logRequest, $config) 84 | { 85 | if ($config->getDuitkuLogs()) { 86 | if (!empty($logRequest)) { 87 | self::writeLogs($config, "Date:" . date('Y-m-d H:i:s')); 88 | self::writeLogs($config, "URL:" . $url); 89 | self::writeLogs($config, "CALLBACK REQUEST:", $logRequest . "\r\n"); 90 | } 91 | } 92 | } 93 | 94 | /** 95 | * Write Log parameter 96 | * 97 | */ 98 | private static function writeLogs($config, $logTitle, $logMessage = '') 99 | { 100 | $rootDirLogs = __DIR__ . "/../logs/"; 101 | 102 | // create dir logs 103 | if (!is_dir($rootDirLogs)) 104 | mkdir($rootDirLogs); 105 | 106 | file_put_contents($rootDirLogs . $config->getLogFileName(), $logTitle . stripslashes($logMessage) . "\r\n", FILE_APPEND | LOCK_EX); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /example/non-composer/lib/Sanitizer.php: -------------------------------------------------------------------------------- 1 | "int|maxLength:50", 17 | "merchantOrderId" => "string|maxLength:50", 18 | "productDetails" => "string|maxLength:255", 19 | "additionalParam" => "string|maxLength:255", 20 | "merchantUserInfo" => "string|maxLength:255", 21 | "customerVaName" => "string|maxLength:20", 22 | "phoneNumber" => "string|maxLength:20|phone", 23 | "expiryPeriod" => "int", 24 | 25 | // itemDetails 26 | "name" => "string|maxLength:50", 27 | "quantity" => "int", 28 | "price" => "int", 29 | 30 | //billingAddress and shippingAddress 31 | 'firstName' => "string|maxLength:50", 32 | 'lastName' => "string|maxLength:50", 33 | 'address' => "string|maxLength:255", 34 | 'city' => "string|maxLength:50", 35 | 'postalCode' => "string|maxLength:50", 36 | 'phone' => "string|maxLength:20|phone", 37 | 'countryCode' => "string|maxLength:50" 38 | ); 39 | 40 | /** 41 | * 42 | * Example: 43 | * 44 | * ```php 45 | * 46 | * $params = array( 47 | * "example1" => "value1", 48 | * "example2" => "value2", 49 | * "example3" => "value3", 50 | * ); 51 | * 52 | * \Duitku\Sanitizer::request($params); 53 | * 54 | * ``` 55 | * 56 | * @param array &$parameterArray 57 | * @return void 58 | */ 59 | public static function Request(&$parameterArray) 60 | { 61 | if (!is_array($parameterArray)) { 62 | return; 63 | } 64 | 65 | foreach ($parameterArray as $rulesLabel => &$parameterValue) { 66 | if (is_array($parameterValue)) { 67 | // parse itemDetails and customerDetail 68 | foreach ($parameterValue as $rulesCustomerDetail => &$parameterCustomerDetail) { 69 | // parse billingAddress and shippingAddress 70 | self::loopParamAddress($parameterCustomerDetail); 71 | 72 | if (isset(self::$_rules[$rulesCustomerDetail])) { 73 | self::sanitizeValue(self::$_rules[$rulesCustomerDetail], $parameterCustomerDetail); 74 | } 75 | } 76 | } 77 | 78 | if (isset(self::$_rules[$rulesLabel])) { 79 | self::sanitizeValue(self::$_rules[$rulesLabel], $parameterValue); 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * Filter field "int|string|maxLength|phone" 86 | * 87 | * @param string $fieldName 88 | * @param string &$parameterValue 89 | * @return void 90 | */ 91 | private static function sanitizeValue($fieldName, &$parameterValue) 92 | { 93 | $attributeTags = explode('|', $fieldName); 94 | rsort($attributeTags); 95 | foreach ($attributeTags as $attributeTag) { 96 | $attributeTagValue = explode(':', $attributeTag); 97 | switch ($attributeTagValue[0]) { 98 | case "string": 99 | $parameterValue = (string)$parameterValue; 100 | break; 101 | case "int": 102 | $parameterValue = (int)$parameterValue; 103 | break; 104 | case "maxLength": 105 | $parameterValue = substr($parameterValue, 0, $attributeTagValue[1]); 106 | break; 107 | case "phone": 108 | $parameterValue = preg_replace("/[^\\d\\-\\(\\)]/", '', $parameterValue); 109 | break; 110 | } 111 | } 112 | } 113 | 114 | /** 115 | * Parse billingAddress and shippingAddress 116 | * 117 | * @param array &$parameterCustomerDetail 118 | * @return void 119 | */ 120 | private static function loopParamAddress(&$parameterCustomerDetail) 121 | { 122 | if (!is_array($parameterCustomerDetail)) { 123 | return; 124 | } 125 | 126 | foreach ($parameterCustomerDetail as $rulesAddress => &$parameterAddress) { 127 | self::sanitizeValue(self::$_rules[$rulesAddress], $parameterAddress); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /tests/CallbackApiTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | // $_POST dummy parameter callback 15 | $paramsCallback = file_get_contents(__DIR__ . '/params/ParamsCallback.json'); 16 | $_POST = json_decode($paramsCallback, true); 17 | 18 | $callback = \Duitku\Api::callback($duitkuConfig); 19 | $notif = json_decode($callback); 20 | 21 | $this->assertEquals($_POST["resultCode"], $notif->resultCode); 22 | $this->assertEquals($_POST["merchantOrderId"], $notif->merchantOrderId); 23 | $this->assertEquals($_POST["reference"], $notif->reference); 24 | $this->assertEquals($_POST["merchantCode"], $notif->merchantCode); 25 | $this->assertEquals($_POST["amount"], $notif->amount); 26 | $this->assertEquals($_POST["signature"], $notif->signature); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/CallbackTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | // $_POST dummy parameter callback 15 | $paramsCallback = file_get_contents(__DIR__ . '/params/ParamsCallback.json'); 16 | $_POST = json_decode($paramsCallback, true); 17 | 18 | $callback = \Duitku\Pop::callback($duitkuConfig); 19 | $notif = json_decode($callback); 20 | 21 | $this->assertEquals($_POST["resultCode"], $notif->resultCode); 22 | $this->assertEquals($_POST["merchantOrderId"], $notif->merchantOrderId); 23 | $this->assertEquals($_POST["reference"], $notif->reference); 24 | $this->assertEquals($_POST["merchantCode"], $notif->merchantCode); 25 | $this->assertEquals($_POST["amount"], $notif->amount); 26 | $this->assertEquals($_POST["signature"], $notif->signature); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/CreateInvoiceApiTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $paymentAmount = 10000; // Amount 15 | $paymentMethod = "BT"; // Permata Bank Virtual Account 16 | $email = "customer@gmail.com"; // your customer email 17 | $phoneNumber = "081234567890"; // your customer phone number (optional) 18 | $productDetails = "Test Payment"; 19 | $merchantOrderId = time(); // from merchant, unique 20 | $additionalParam = ''; // optional 21 | $merchantUserInfo = ''; // optional 22 | $customerVaName = 'John Doe'; // display name on bank confirmation display 23 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 24 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 25 | $expiryPeriod = 60; // set the expired time in minutes 26 | 27 | // Customer Detail 28 | $firstName = "John"; 29 | $lastName = "Doe"; 30 | 31 | // Address 32 | $alamat = "Jl. Kembangan Raya"; 33 | $city = "Jakarta"; 34 | $postalCode = "11530"; 35 | $countryCode = "ID"; 36 | 37 | $address = array( 38 | 'firstName' => $firstName, 39 | 'lastName' => $lastName, 40 | 'address' => $alamat, 41 | 'city' => $city, 42 | 'postalCode' => $postalCode, 43 | 'phone' => $phoneNumber, 44 | 'countryCode' => $countryCode 45 | ); 46 | 47 | $customerDetail = array( 48 | 'firstName' => $firstName, 49 | 'lastName' => $lastName, 50 | 'email' => $email, 51 | 'phoneNumber' => $phoneNumber, 52 | 'billingAddress' => $address, 53 | 'shippingAddress' => $address 54 | ); 55 | 56 | 57 | // Item Details 58 | $item1 = array( 59 | 'name' => $productDetails, 60 | 'price' => $paymentAmount, 61 | 'quantity' => 1 62 | ); 63 | 64 | 65 | $itemDetails = array( 66 | $item1 67 | ); 68 | 69 | $params = array( 70 | 'paymentAmount' => $paymentAmount, 71 | 'paymentMethod' => $paymentMethod, 72 | 'merchantOrderId' => $merchantOrderId, 73 | 'productDetails' => $productDetails, 74 | 'additionalParam' => $additionalParam, 75 | 'merchantUserInfo' => $merchantUserInfo, 76 | 'customerVaName' => $customerVaName, 77 | 'email' => $email, 78 | 'phoneNumber' => $phoneNumber, 79 | 'itemDetails' => $itemDetails, 80 | 'customerDetail' => $customerDetail, 81 | 'callbackUrl' => $callbackUrl, 82 | 'returnUrl' => $returnUrl, 83 | 'expiryPeriod' => $expiryPeriod 84 | ); 85 | 86 | // createInvoice Request 87 | $responseDuitkuPop = \Duitku\Api::createInvoice($params, $duitkuConfig); 88 | $payment = json_decode($responseDuitkuPop); 89 | 90 | 91 | $this->assertEquals("00", $payment->statusCode); 92 | $this->assertEquals("SUCCESS", $payment->statusMessage); 93 | $this->assertEquals($duitkuConfig->getMerchantCode(), $payment->merchantCode); 94 | $this->assertNotEmpty($payment->reference); 95 | $this->assertNotEmpty($payment->paymentUrl); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tests/CreateInvoiceTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $paymentAmount = 10000; // Amount 15 | $email = "customer@gmail.com"; // your customer email 16 | $phoneNumber = "081234567890"; // your customer phone number (optional) 17 | $productDetails = "Test Payment"; 18 | $merchantOrderId = time(); // from merchant, unique 19 | $additionalParam = ''; // optional 20 | $merchantUserInfo = ''; // optional 21 | $customerVaName = 'John Doe'; // display name on bank confirmation display 22 | $callbackUrl = 'http://YOUR_SERVER/callback'; // url for callback 23 | $returnUrl = 'http://YOUR_SERVER/return'; // url for redirect 24 | $expiryPeriod = 60; // set the expired time in minutes 25 | 26 | // Customer Detail 27 | $firstName = "John"; 28 | $lastName = "Doe"; 29 | 30 | // Address 31 | $alamat = "Jl. Kembangan Raya"; 32 | $city = "Jakarta"; 33 | $postalCode = "11530"; 34 | $countryCode = "ID"; 35 | 36 | $address = array( 37 | 'firstName' => $firstName, 38 | 'lastName' => $lastName, 39 | 'address' => $alamat, 40 | 'city' => $city, 41 | 'postalCode' => $postalCode, 42 | 'phone' => $phoneNumber, 43 | 'countryCode' => $countryCode 44 | ); 45 | 46 | $customerDetail = array( 47 | 'firstName' => $firstName, 48 | 'lastName' => $lastName, 49 | 'email' => $email, 50 | 'phoneNumber' => $phoneNumber, 51 | 'billingAddress' => $address, 52 | 'shippingAddress' => $address 53 | ); 54 | 55 | 56 | // Item Details 57 | $item1 = array( 58 | 'name' => $productDetails, 59 | 'price' => $paymentAmount, 60 | 'quantity' => 1 61 | ); 62 | 63 | 64 | $itemDetails = array( 65 | $item1 66 | ); 67 | 68 | $params = array( 69 | 'paymentAmount' => $paymentAmount, 70 | 'merchantOrderId' => $merchantOrderId, 71 | 'productDetails' => $productDetails, 72 | 'additionalParam' => $additionalParam, 73 | 'merchantUserInfo' => $merchantUserInfo, 74 | 'customerVaName' => $customerVaName, 75 | 'email' => $email, 76 | 'phoneNumber' => $phoneNumber, 77 | 'itemDetails' => $itemDetails, 78 | 'customerDetail' => $customerDetail, 79 | 'callbackUrl' => $callbackUrl, 80 | 'returnUrl' => $returnUrl, 81 | 'expiryPeriod' => $expiryPeriod 82 | ); 83 | 84 | // createInvoice Request 85 | $responseDuitkuPop = \Duitku\Pop::createInvoice($params, $duitkuConfig); 86 | $payment = json_decode($responseDuitkuPop); 87 | 88 | 89 | $this->assertEquals("00", $payment->statusCode); 90 | $this->assertEquals("SUCCESS", $payment->statusMessage); 91 | $this->assertEquals($duitkuConfig->getMerchantCode(), $payment->merchantCode); 92 | $this->assertNotEmpty($payment->reference); 93 | $this->assertNotEmpty($payment->paymentUrl); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/GetPaymentMethodApiTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 15 | $paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $duitkuConfig); 16 | 17 | $paymentMethod = json_decode($paymentMethodList); 18 | 19 | $this->assertEquals("00", $paymentMethod->responseCode); 20 | $this->assertEquals("SUCCESS", $paymentMethod->responseMessage); 21 | $this->assertNotEmpty($paymentMethod->paymentFee); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/GetPaymentMethodTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $paymentAmount = "10000"; //"YOUR_AMOUNT"; 15 | $paymentMethodList = \Duitku\Pop::getPaymentMethod($paymentAmount, $duitkuConfig); 16 | 17 | $paymentMethod = json_decode($paymentMethodList); 18 | 19 | $this->assertEquals("00", $paymentMethod->responseCode); 20 | $this->assertEquals("SUCCESS", $paymentMethod->responseMessage); 21 | $this->assertNotEmpty($paymentMethod->paymentFee); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TransactionStatusApiTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 15 | $transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $duitkuConfig); 16 | 17 | $transaction = json_decode($transactionList); 18 | 19 | $this->assertEquals("00", $transaction->statusCode); 20 | $this->assertEquals("SUCCESS", $transaction->statusMessage); 21 | $this->assertEquals($merchantOrderId, $transaction->merchantOrderId); 22 | $this->assertNotEmpty($transaction->reference); 23 | $this->assertNotEmpty($transaction->amount); 24 | $this->assertNotEmpty($transaction->fee); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/TransactionStatusTest.php: -------------------------------------------------------------------------------- 1 | setSandboxMode(true); 13 | 14 | $merchantOrderId = "1"; //"YOUR_MERCHANTORDERID"; 15 | $transactionList = \Duitku\Pop::transactionStatus($merchantOrderId, $duitkuConfig); 16 | 17 | $transaction = json_decode($transactionList); 18 | 19 | $this->assertEquals("00", $transaction->statusCode); 20 | $this->assertEquals("SUCCESS", $transaction->statusMessage); 21 | $this->assertEquals($merchantOrderId, $transaction->merchantOrderId); 22 | $this->assertNotEmpty($transaction->reference); 23 | $this->assertNotEmpty($transaction->amount); 24 | $this->assertNotEmpty($transaction->fee); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/params/ParamsCallback.json: -------------------------------------------------------------------------------- 1 | { 2 | "merchantOrderId": "12345", 3 | "resultCode": "00", 4 | "merchantCode": "D0001", 5 | "amount": 10000, 6 | "productDetail": "", 7 | "paymentCode": "", 8 | "reference": "D00015HL5BJKRM27MCUS", 9 | "additionalParam": "", 10 | "signature": "4104f20a70c933113c66c004fe25a9f1" 11 | } --------------------------------------------------------------------------------