Показаны сообщения с ярлыком UPC. Показать все сообщения
Показаны сообщения с ярлыком UPC. Показать все сообщения

понедельник, 3 декабря 2012 г.

UPC eCommerceConnect Интеграция на платформе .NET: Часть 2. Программирование

Это вторая часть цикла статей, посвященных интеграции UPC
ВСЕ ЧАСТИ МАТЕРИАЛА

Пример на ASP.NET MVC3
Теперь собственно этап программирования

что имеем:
1. на руках есть XXXXXXX.pem файл с приватным ключем, с помощью которого нужно по определенным правилом зашифровать сообщение
2. раздел документации: "Интерфейс взаимодействия. Руководство администратора торговой системы."
http://ecommerce.upc.ua/docs/shop_gateway_interface.pdf

3. тема на форуме "Пример подключения для платформы .net со всеми деталями"
http://forum.ecommerce.upc.ua/viewtopic.php?f=12&t=468
(скажу сразу, что пример помог, но часть процедур пришлось додумывать самостоятельно)

1. Готовим объект - шлюз
Этот объект нам нужен для отображения полей формы
Как-то так. Если где ошибся с типами, вопросы/пожелания/предложения принимаются.
public class objectEccGateway: MegaUtils_V3.objects.objectMegaBase
{
public int Version;
public string MerchantID;
public string TerminalID;
public long TotalAmount;
public int Currency;
public string Locale; //ru
public string OrderID;
public string PurchaseTime;
public string Gateway;
public string SD;
public string PurchaseDesc;

public string XID;
public string ProxyPanResponse;
public string ApprovalCode;
public int TranCode;
public Int64 Rrn;

public string Signature;
}

2. Готовим объект - параметры системы
В этом объекте я настраивал параметры системы UPC

public class objectCatalogPaymentSystemUPC
{
public string MerchantId;

public string TerminalId;

public string CertificateFile;

public string Gateway;

}

3. Готовим утилиты для работы с файлами ключей

для парсинга приватного ключа из *.pem файла
помогло решение из статьи
http://stackoverflow.com/questions/1162504/decrypting-with-private-key-from-pem-file-in-c-sharp-with-net-crypto-library/1162519#1162519
в статье есть ссылка на файл
http://www.jensign.com/opensslkey/opensslkey.cs

который я взял и полностью вставил в код

(правда одну строчку пришлось закомментиовать там было "(сертификат)UI" - .NET не распознал её как идентификатор. на работоспособности системы она не отразилась)

эта статья тоже ссылается на правильное решение
http://stackoverflow.com/questions/243646/how-to-read-a-pem-rsa-private-key-from-net

также помогла функция PEM отсюда
http://pages.infinit.net/ctech/20040812-0816.html

на эту функцию вела статья
http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvcs/thread/348e1909-4da9-4980-94fc-f412dce07690/

в конце концов код выглядел так:

public class RSACryptoUtils
{
public static string RSASign(string data, string KeyFile)
{

RSACryptoServiceProvider rsaCsp =
LoadCertificateFile(KeyFile);

if (rsaCsp == null) return String.Empty;

byte[] dataBytes = Encoding.UTF8.GetBytes(data);

byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");

return Convert.ToBase64String(signatureBytes);

}

public static byte[] PEM(string type, byte[] data)
{
string pem = Encoding.ASCII.GetString(data);
string header = String.Format("-----BEGIN {0}-----", type);
string footer = String.Format("-----END {0}-----", type);
int start = pem.IndexOf(header) + header.Length;
int end = pem.IndexOf(footer, start);
string base64 = pem.Substring(start, (end - start));
return Convert.FromBase64String(base64);
}


public static RSACryptoServiceProvider LoadCertificateFile(string filename)
{
using (FileStream fs = File.OpenRead(filename))
{
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);

if (data[0] != 0x30)
{
// maybe it's ASCII PEM base64 encoded ?
data = PEM("RSA PRIVATE KEY", data);
}
if (data != null)
return opensslkey.DecodeRSAPrivateKey(data);
//x509 = new X509Certificate2(data);

throw new ApplicationException("error");

}
//return x509;
throw new ApplicationException("error");
}
}
4. Готовим функцию, которая возвращает объект "поля формы"
/// <summary>
/// Подготовить поля веб-формы для отправки на сервер
/// </summary>
/// <param name="aUPCParams">параметры мерчанта</param>
/// <param name="aLocale">язык интерфейса "ru" или "en"</param>
/// <param name="aDocRecID">код докуента</param>
/// <param name="aTotalAmont">сумма доакмента</param>
/// <param name="aCurrencyRecID">код валюты 980-гривна</param>
/// <param name="aSessionID">код сессии System.Web.HttpContext.Current.Session.SessionID</param>
/// <returns></returns>
public static objects.objectEccGateway GetRequestFormFields(
objectCatalogPaymentSystemUPC aUPCParams,
string aLocale,
string aDocRecID,
double aTotalAmont,
int aCurrencyRecID,
string aSessionID
)
{
var obj = new tfoBookingUtils.PaymentSystem.UPC.objects.objectEccGateway()
{
Version = 1,
MerchantID = aUPCParams.MerchantId,
TerminalID = aUPCParams.TerminalId,
TotalAmount = (long)(aTotalAmont * 100),
Currency = aCurrencyRecID, //
Locale = aLocale,
OrderID = aDocRecID + "|" + DateTime.Now.ToString("yyMMddHHmmss"),
PurchaseTime = DateTime.Now.ToString("yyMMddHHmmss"),
Gateway = aUPCParams.Gateway,
SD = aSessionID,

PurchaseDesc = string.Format("Заказ {0} на сумму {1:N} грн.", aDocRecID, aTotalAmont)
};

string str = String.Format("{0};{1};{2};{3};{4};{5};{6};",
obj.MerchantID, obj.TerminalID, obj.PurchaseTime, obj.OrderID,
obj.Currency, obj.TotalAmount, obj.SD);
obj.Signature = RSACryptoUtils.RSASign(str, System.Web.HttpContext.Current.Server.MapPath(aUPCParams.CertificateFile));

return obj;
}
5. Готовим форму отправки запроса. отображаем поля формы во вьюшке

@model objectEccGateway;
...
<form action="@Model.Gateway" method="post" id="ecommerce_pay">
<input type="hidden" name="Version" value="@Model.Version" />
<input type="hidden" name="MerchantID" value="@Model.MerchantID" />
<input type="hidden" name="TerminalID" value="@Model.TerminalID" />
<input type="hidden" name="TotalAmount" value="@Model.TotalAmount" />
<input type="hidden" name="Currency" value="@Model.Currency" />
<input type="hidden" name="locale" value="@Model.Locale" />
<input type="hidden" name="SD" value="@Model.SD" />
<input type="hidden" name="OrderID" value="@Model.OrderID" />
<input type="hidden" name="PurchaseTime" value="@Model.PurchaseTime" />
<input type="hidden" name="PurchaseDesc" value="@Model.PurchaseDesc" />
<input type="hidden" name="Signature" value="@Model.Signature" />
<input type="submit" name="submit" value="Оплатить" />
</form>
...
6. Обрабтываем результат

В экшене-обработчике результата
пишеи примерно такое

ecc = new objectEccGateway()
{
MerchantID = Request.Params["MerchantID"],
OrderID = Request.Params["OrderID"],
//PurchaseTime = Convert.ToInt64(Request.Params["PurchaseTime"]),
SD = Request.Params["SD"],
TerminalID = Request.Params["TerminalID"],
ProxyPanResponse = Request.Params["ProxyPan"],
Currency = Convert.ToInt32(Request.Params["Currency"]),
ApprovalCode = Request.Params["ApprovalCode"],
Signature = Request.Params["Signature"],
Rrn = Convert.ToInt64(Request.Params["Rrn"]),
XID = Request.Params["XID"],
TranCode = Convert.ToInt32(Request.Params["TranCode"]),
TotalAmount = Convert.ToInt64(Request.Params["TotalAmount"])
};



if (Convert.ToInt32(Request.Params["TranCode"]) == 0)
{
//ok
}
else{
//error
}

UPC eCommerceConnect Интеграция на платформе .NET: Часть 1. Организационные вопросы

Это первая часть цикла статей, посвященных интеграции UPC

ВСЕ ЧАСТИ МАТЕРИАЛА




Для начала работы я завел свой тестовый аккаунт
1. Заявка на регистрацию

1. скачал отсюда http://ecommerce.upc.ua/docs.html
2. заполнил своими реквизитами (написал, что модуль нужен в тестовых целях)
3. отправил на адрес ec@upc.ua
Получаю ответ на заявку
(в моем случае менеджеры системы откликнулись быстро, это заняло порядка 15-ти минут)



Ответ выглядит примерно так:

Здравствуйте,

Тестовые данные:


Адрес шлюза : https://secure.upc.ua/ecgtest/enter
MerchantID=XXXXXXX

TerminalID=YYYYYYY
Интерфейс торговца :https://secure.upc.ua/ecgtest/merchant
Логин / Пароль :XXXXXXX/в следующем письме

Сертификат сервера - в аттаче

Также необходимо, чтобы Вы выслали сертификат торговца (файл с именем XXXXXXX.crt) на адрес ec@upc.ua

Вся необходимая документация: здесь: http://ecommerce.upc.ua/site/docs.html
Тестовые карты здесь: http://ecommerce.upc.ua/docs/Testing.pdf
(See attached file: test-server.cert)
В архиве batch.rar документация и примеры по формированию подписи.

(See attached file: batch.rar)
password: 1

где
XXXXXXX-код мерчанта
YYYYYYYY-код терминала
Согласно письма, следующее действие - подготовка ключей и сертификатов

2. Подготовка ключей и сертификатов
(эту часть делаем согласно readme-файла вложенного письма, только с поправкой на 64-х битность Windows-системы)
1. Выкачиваю OpenSSL-библиотеки
с сайта http://slproweb.com/products/Win32OpenSSL.html
Выкачиваю такие файлы
Visual C++ 2008 Redistributables (x64)
тут шла ссылка на сайт микрософт
Win64 OpenSSL v1.0.1c Light
тут версия 1.0.1с актуальна на 2012 12
2. Запускаю выкачанные инсталлянты
По умолчанию библиотеки OpenSSL установились в директорию C:\OpenSSL-Win64

3. Прописываю библиотеки в переменной Path
(пример для Windows 7 x64)
Панель управления\Все элементы панели управления\Система

дополнительные параметры системы

вкладка "Дополнительно" кнопка "Переменные среды"
Область "системные переменные"
переменная PATH

Добавляю тута путь: C:\OpenSSL-Win64\bin
4. правлю конфиг-файл config.dat
устанавливаю там параметры согласно заявке
(поля в разделе [req] не трогал)

5. Собственно гененрирую файлы ключей и сертификатов
для этого запускаю

run.bat XXXXXXX

где
XXXXXXX-мой код мерчанта
На выходе получаю файлы
XXXXXXX.pem – приватный ключ
XXXXXXX.pub – публичный ключ
XXXXXXX.crt – сертификат
6. Файл сертификата (*.crt) отправляю в UPC на адрес ec@upc.ua
7. Получаю ответ от UPC
В моем случае все было достаточно быстро и лаконично : "подгружен"
Еще я естествеено проверил их веб-интерфейс залогинившись под своим именем/паролем.
Пароль, кстати, система сразу предложила сменить.

3. Настройка путей ответа.
в веб-интерфейсе заходим в раздел "терминалы". выбираем редактированиее терминала.
и заполняем поля:
страницы для ответов сервера (эти страницы должны быть в вашем веб-приложении и содержать обработку ответов сервера).

UPC eCommerceConnect Интеграция на платформе .NET

Делал интеграцию платежной системы UPC на платформе .NET

Возможно мой опыт кому-то окажется полезен.

материала достаточно много, поэтому разбил на части

1. Орг вопросы
2. Программирование
3. Тестирование

Пожелания/предложения принимаются в комментариях.

ссылки по теме:
Сайт платежной системы
http://ecommerce.upc.ua/
Сайт организации-владельца системы
https://upc.ua/ua.htm
Документация по системе
http://ecommerce.upc.ua/docs.html
блог разработчика с полезной информацией
http://mac-blog.org.ua/upc-visa-mastercard-payment/
форум
http://forum.ecommerce.upc.ua/viewforum.php?f=9