Исходный код метода:
$this->language->load('payment/klarna_invoice');
$json = array();
$this->load->model('checkout/order');
$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
// Order must have identical shipping and billing address or have no shipping address at all
if ($order_info) {
if ($order_info['payment_iso_code_3'] == 'DEU' && empty($this->request->post['deu_terms'])) {
$json['error'] = $this->language->get('error_deu_terms');
}
if ($this->cart->hasShipping() && !($order_info['payment_firstname'] == $order_info['shipping_firstname'] && $order_info['payment_lastname'] == $order_info['shipping_lastname'] && $order_info['payment_address_1'] == $order_info['shipping_address_1'] && $order_info['payment_address_2'] == $order_info['shipping_address_2'] && $order_info['payment_postcode'] == $order_info['shipping_postcode'] && $order_info['payment_city'] == $order_info['shipping_city'] && $order_info['payment_zone_id'] == $order_info['shipping_zone_id'] && $order_info['payment_zone_code'] == $order_info['shipping_zone_code'] && $order_info['payment_country_id'] == $order_info['shipping_country_id'] && $order_info['payment_country'] == $order_info['shipping_country'] && $order_info['payment_iso_code_3'] == $order_info['shipping_iso_code_3'])) {
$json['error'] = $this->language->get('error_address_match');
}
if (!$json) {
$klarna_invoice = $this->config->get('klarna_invoice');
if ($klarna_invoice[$order_info['payment_iso_code_3']]['server'] == 'live') {
$url = 'https://payment.klarna.com/';
} else {
$url = 'https://payment.testdrive.klarna.com/';
}
$country_to_currency = array(
'NOR' => 'NOK',
'SWE' => 'SEK',
'FIN' => 'EUR',
'DNK' => 'DKK',
'DEU' => 'EUR',
'NLD' => 'EUR',
);
switch ($order_info['payment_iso_code_3']) {
// Sweden
case 'SWE':
$country = 209;
$language = 138;
$encoding = 2;
$currency = 0;
break;
// Finland
case 'FIN':
$country = 73;
$language = 37;
$encoding = 4;
$currency = 2;
break;
// Denmark
case 'DNK':
$country = 59;
$language = 27;
$encoding = 5;
$currency = 3;
break;
// Norway
case 'NOR':
$country = 164;
$language = 97;
$encoding = 3;
$currency = 1;
break;
// Germany
case 'DEU':
$country = 81;
$language = 28;
$encoding = 6;
$currency = 2;
break;
// Netherlands
case 'NLD':
$country = 154;
$language = 101;
$encoding = 7;
$currency = 2;
break;
}
if (isset($this->request->post['street'])) {
$street = $this->request->post['street'];
} else {
$street = $order_info['payment_address_1'];
}
if (isset($this->request->post['house_no'])) {
$house_no = $this->request->post['house_no'];
} else {
$house_no = '';
}
if (isset($this->request->post['house_ext'])) {
$house_ext = $this->request->post['house_ext'];
} else {
$house_ext = '';
}
$address = array(
'email' => $order_info['email'],
'telno' => $this->request->post['phone_no'],
'cellno' => '',
'fname' => $order_info['payment_firstname'],
'lname' => $order_info['payment_lastname'],
'company' => $order_info['payment_company'],
'careof' => '',
'street' => $street,
'house_number' => $house_no,
'house_extension' => $house_ext,
'zip' => $order_info['payment_postcode'],
'city' => $order_info['payment_city'],
'country' => $country,
);
$product_query = $this->db->query("SELECT `name`, `model`, `price`, `quantity`, `tax` / `price` * 100 AS 'tax_rate' FROM `" . DB_PREFIX . "order_product` WHERE `order_id` = " . (int)$order_info['order_id'] . " UNION ALL SELECT '', `code`, `amount`, '1', 0.00 FROM `" . DB_PREFIX . "order_voucher` WHERE `order_id` = " . (int)$order_info['order_id'])->rows;
foreach ($product_query as $product) {
$goods_list[] = array(
'qty' => (int)$product['quantity'],
'goods' => array(
'artno' => $product['model'],
'title' => $product['name'],
'price' => (int)str_replace('.', '', $this->currency->format($product['price'], $country_to_currency[$order_info['payment_iso_code_3']], '', false)),
'vat' => (float)$product['tax_rate'],
'discount' => 0.0,
'flags' => 0,
)
);
}
if (isset($this->session->data['klarna'][$this->session->data['order_id']])) {
$totals = $this->session->data['klarna'][$this->session->data['order_id']];
} else {
$totals = array();
}
foreach ($totals as $total) {
if ($total['code'] != 'sub_total' && $total['code'] != 'tax' && $total['code'] != 'total') {
$goods_list[] = array(
'qty' => 1,
'goods' => array(
'artno' => '',
'title' => $total['title'],
'price' => (int)str_replace('.', '', $this->currency->format($total['value'], $country_to_currency[$order_info['payment_iso_code_3']], '', false)),
'vat' => (float)$total['tax_rate'],
'discount' => 0.0,
'flags' => 0,
)
);
}
}
$digest = '';
foreach ($goods_list as $goods) {
$digest .= utf8_decode(htmlspecialchars(html_entity_decode($goods['goods']['title'], ENT_COMPAT, "UTF-8"))) . ':';
}
$digest = base64_encode(pack('H*', hash('sha256', $digest . $klarna_invoice[$order_info['payment_iso_code_3']]['secret'])));
if (isset($this->request->post['pno'])) {
$pno = $this->request->post['pno'];
} else {
$pno = sprintf('%02d', (int)$this->request->post['pno_day']) . sprintf('%02d', (int)$this->request->post['pno_month']) . (int)$this->request->post['pno_year'];
}
$pclass = -1;
if (isset($this->request->post['gender']) && ($order_info['payment_iso_code_3'] == 'DEU' || $order_info['payment_iso_code_3'] == 'NLD')) {
$gender = (int)$this->request->post['gender'];
} else {
$gender = '';
}
$transaction = array(
'4.1',
'API:OPENCART:' . VERSION,
$pno,
$gender,
'',
'',
(string)$order_info['order_id'],
'',
$address,
$address,
$order_info['ip'],
0,
$currency,
$country,
$language,
(int)$klarna_invoice[$order_info['payment_iso_code_3']]['merchant'],
$digest,
$encoding,
$pclass,
$goods_list,
$order_info['comment'],
array('delay_adjust' => 1),
array(),
array(),
array(),
array(),
array(),
);
$xml = '<methodCall>';
$xml .= ' <methodName>add_invoice</methodName>';
$xml .= ' <params>';
foreach ($transaction as $parameter) {
$xml .= ' <param><value>' . $this->constructXmlrpc($parameter) . '</value></param>';
}
$xml .= ' </params>';
$xml .= '</methodCall>';
$header = 'Content-Type: text/xml' . "\n";
$header .= 'Content-Length: ' . strlen($xml) . "\n";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER, $header);
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
$response = curl_exec($curl);
if (curl_errno($curl)) {
$log = new Log('klarna_invoice.log');
$log->write('HTTP Error for order #' . $order_info['order_id'] . '. Code: ' . curl_errno($curl) . ' message: ' . curl_error($curl));
$json['error'] = $this->language->get('error_network');
} else {
preg_match('/<member><name>faultString<\/name><value><string>(.+)<\/string><\/value><\/member>/', $response, $match);
if (isset($match[1])) {
preg_match('/<member><name>faultCode<\/name><value><int>([0-9]+)<\/int><\/value><\/member>/', $response, $match2);
$log = new Log('klarna_invoice.log');
$log->write('Failed to create an invoice for order #' . $order_info['order_id'] . '. Message: ' . utf8_encode($match[1]) . ' Code: ' . $match2[1]);
$json['error'] = utf8_encode($match[1]);
} else {
$xml = new DOMDocument();
$xml->loadXML($response);
$invoice_number = $xml->getElementsByTagName('string')->item(0)->nodeValue;
$klarna_order_status = $xml->getElementsByTagName('int')->item(0)->nodeValue;
if ($klarna_order_status == '1') {
$order_status = $klarna_invoice[$order_info['payment_iso_code_3']]['accepted_status_id'];
} elseif ($klarna_order_status == '2') {
$order_status = $klarna_invoice[$order_info['payment_iso_code_3']]['pending_status_id'];
} else {
$order_status = $this->config->get('config_order_status_id');
}
$comment = sprintf($this->language->get('text_comment'), $invoice_number, $this->config->get('config_currency'), $country_to_currency[$order_info['payment_iso_code_3']], $this->currency->getValue($country_to_currency[$order_info['payment_iso_code_3']]));
$this->model_checkout_order->confirm($this->session->data['order_id'], $order_status, $comment, 1);
$json['redirect'] = $this->url->link('checkout/success');
}
}
curl_close($curl);
}
}
$this->response->setOutput(json_encode($json));