/** * SetExpressCheckout * @param integer $invnum Идентификатор платежа, показывается клиенту в поле Invoice ID. * @param double $amt * @param string $currencycode * @param string $subscription Описание, которое пользователь видит рядом с галкой автоматических платежей * @param [key => value] $addParams Другие параметры SetExpressCheckout * @return integer|null transactionId */ public function initiateTransaction($invnum, $amt, $currencycode, $subscription = null, $addParams = []) { $params = ['USER' => $this->user, 'PWD' => $this->password, 'SIGNATURE' => $this->signature, 'VERSION' => $this->apiVersion, 'METHOD' => 'SetExpressCheckout', 'PAYMENTREQUEST_0_AMT' => $amt, 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale', 'PAYMENTREQUEST_0_CURRENCYCODE' => $currencycode, 'PAYMENTREQUEST_0_INVNUM' => $invnum, 'RETURNURL' => \WebConstructionSet\Url\Tools::getMyUrl(), 'CANCELURL' => \WebConstructionSet\Url\Tools::getMyUrl()]; if ($subscription) { $params['L_BILLINGTYPE0'] = 'MerchantInitiatedBilling'; $params['L_BILLINGAGREEMENTDESCRIPTION0'] = $subscription; } $params = array_merge($params, $addParams); $result = $this->call($params); if ($result) { if (isset($result['TOKEN'])) { if ($id = $this->transactions->insert(['time' => time(), 'invnum' => $invnum, 'amt' => $amt, 'currencycode' => $currencycode, 'token' => $result['TOKEN']])) { return $id; } } } return null; }
/** * @param string $orderNumber * @param double $amount * @param string $currency * @param boolean $subscription recurring payments * @param [key => value] $addParams * @return integer|null Transaction ID */ public function initiateTransaction($orderNumber, $amount, $currency, $subscription = false, $addParams = []) { $transaction = ['time' => time(), 'order_number' => $orderNumber, 'amount' => $amount, 'currency' => $currency]; $params = ['Merchant_ID' => $this->merchantId, 'OrderNumber' => $orderNumber, 'OrderAmount' => $amount, 'OrderCurrency' => $currency, 'URL_RETURN' => \WebConstructionSet\Url\Tools::getMyUrl()]; if ($subscription) { $params['RecurringIndicator'] = 1; $params['RecurringMinAmount'] = 0.01; $params['RecurringMaxAmount'] = 1000; $params['RecurringPeriod'] = 1; $params['RecurringMaxDate'] = date('d.m.Y', time() + 86400 * 365 * 2); $transaction['recurring'] = 1; } $params = array_merge($params, $addParams); $data = md5($this->secretWord) . md5($params['Merchant_ID'] . ';' . $params['OrderNumber'] . ';' . $params['OrderAmount'] . ';' . $params['OrderCurrency']); $checkvalue = strtoupper(md5(strtoupper($data))); $params['Checkvalue'] = $checkvalue; if ($this->secretKey) { $data = md5($params['Merchant_ID'] . ';' . $params['OrderNumber'] . ';' . $params['OrderAmount'] . ';' . $params['OrderCurrency'], true); if (!openssl_sign($data, $signature, $this->secretKey)) { error_log(new \ErrorException('openssl_sign failed, order_number: ' . $orderNumber, null, null, __FILE__, __LINE__)); return null; } $signature = base64_encode($signature); $params['Signature'] = $signature; } $result = $this->call('/pay/order.cfm', $params, true); if (!$result || !isset($result['location'])) { error_log(new \ErrorException('Location is missing, result: ' . json_encode($result), null, null, __FILE__, __LINE__)); return null; } $transaction['url'] = $result['location']; if (strpos($transaction['url'], '://') === false) { $transaction['url'] = 'https://' . $this->server . $transaction['url']; } if (preg_match('/ErrorID=/', $transaction['url'])) { $data = @file_get_contents($transaction['url'], false); error_log(new \ErrorException('Url contains error description, order_number: ' . $orderNumber . ', transaction: ' . json_encode($transaction) . ', result: ' . json_encode($result) . ', data: ' . $data, null, null, __FILE__, __LINE__)); return null; } $params = ['Merchant_ID' => $this->merchantId, 'Login' => $this->login, 'Password' => $this->password, 'Format' => 3, 'OrderNumber' => $orderNumber]; $result = $this->call('/orderstate/orderstate.cfm', $params, false); if (!$result) { return null; } if (!isset($result['order'])) { error_log(new \ErrorException('Order is missing, result: ' . json_encode($result), null, null, __FILE__, __LINE__)); return null; } $order = $result['order']; $checkvalue = md5($this->secretWord) . md5($this->merchantId . $order['ordernumber'] . $order['orderamount'] . $order['ordercurrency'] . $order['orderstate']); $checkvalue = strtoupper(md5(strtoupper($checkvalue))); if ($checkvalue != $order['checkvalue']) { error_log(new \ErrorException('checkvalue mismatch, computed: ' . $checkvalue . ', actual: ' . $order['checkvalue'] . ', result: ' . json_encode($result), null, null, __FILE__, __LINE__)); return null; } $transaction['bill_number'] = $order['billnumber']; if ($order['orderstate'] != 'In Process') { error_log(new \ErrorException('Bad order state, order: ' . json_encode($order), null, null, __FILE__, __LINE__)); return null; } return $this->transactions->insert($transaction); }