Сервис может быть инициализирован двумя способами:
- с передачей параметров serviceId и secret:
RFIPayService * payService = [[RFIPayService alloc] initWithServiceId:@"12345" andSecret:@"abcd1234"];
- с передачей параметров serviceId и key:
RFIPayService * payService = [[RFIPayService alloc] initWithServiceId:@"12345" andKey:@"abcd1234"];
Для проведения оплаты банковской картой с вводом карточных данных необходимо сначала создать токен содержащий данные, а затем использовать его для инициации платежа. Данные, необходимые для создания токена, содержатся в RFICardTokenRequest. Если карта требует проведения 3-D Secure проверку, то paymentResponse.card3ds будет содержать данные для POST запроса на сайт банка-эмитента.
Инициализируем запрос RFICardTokenRequest:
RFICardTokenRequest * cardTokenRequest = [[RFICardTokenRequest alloc] initWithServiceId:payService.serviceId andCard:@"<Номер карты>" andExpMonth:@"<Месяц>" andExpYear:@"<Год>" andCvc:@"<CVC>" andCardHolder:@"<Владелец карты>"];
RFICardTokenResponse * cardTokenResponse = [payService createCardToken:cardTokenRequest isTest:YES];
Запрашиваем токен карты. Метод [RFIPayService createCardToken: isTest: successBlock: failure:] выполняется асинхронно. В случае, если ответ от Банка получен, выполняется successBlock, в противном - failure:
[payService createCardToken:cardTokenRequest isTest:YES successBlock:^(RFICardTokenResponse *response) {
// обработка ответа от Банка
} failure:^(NSDictionary *error) {
// обработка ошибки
}];
Если cardTokenResponse.hasErrors == NO, инициализируем транзакцию:
// Генерируем запрос на оплату
RFIPaymentRequest * paymentRequest = [[RFIPaymentRequest alloc] init];
// Собираем необходимые параметры для платежа
paymentRequest.paymentType = @"spg_test"; // Варинаты: mc, qiwi, spg, spg_test
paymentRequest.email = @"<Email>"; // Может быть обязательным, в зависисмости от настроек сервиса
paymentRequest.cost = @"<Сумма>"; // в целых
paymentRequest.name = @"<Название платежа>";
paymentRequest.phone = @"<Номер телефона>"; // Обязательно, если канал оплаты mc, qiwi
paymentRequest.orderId = @"<Номер заказа>"; // Номер заказа должен быть уникальным. Необязательное поле
paymentRequest.background = @"1"; // Всегда ставим 1
paymentRequest.cardToken = cardTokenResponse.token; // В случае, если канал оплаты spg или spg_test
paymentRequest.comment = @"<Комментарий>"; // Необязательное поле
В случае, если платеж рекуррентный, то paymentRequest необходимо передать дополнительные параметры, описанные в RFIReccurentParams. Рекуррентный платеж (РП) состоит из двух операций:
- платеж с регистрацией рекуррентного платежа (для первого РП)
NSString *url = @"<Ссылка на подробное описание правил предоставления рекуррентного платежа>";
NSString *comment = @"<Текстовое описание за что производится регистрация РП>";
RFIReccurentParams *reccurentParams = [RFIReccurentParams firstWithUrl:url andComment:comment];
- рекуррентный платеж по требованию (все последующие РП)
NSString *reccurentOrderId = @"<номер заказа>";
RFIReccurentParams *reccurentParams = [RFIReccurentParams nextWithOrderId:reccurentOrderId];
Затем передаем параметры рекуррентного платежа запросу на оплату:
paymentRequest.reccurentParams = reccurentParams;
Отменить рекуррентные платежи можно следующим методом:
[payService cancelRecurrentPaymentWithOrderId:reccurentOrderId successBlock:^{
// обработка ответа от Банка
} failure:^(NSDictionary *error) {
// обработка ошибки
}];
Если нужно добавить данные чека для фискализации, то необходимо создать объект RFIInvoiceData и передать его в параметре paymentRequest:
RFIInvoiceData *invoiceData = [RFIInvoiceData new];
invoiceData.vatTotal = @(<стоимость>);
RFIInvoiceItem *firstItem = [RFIInvoiceItem new];
firstItem.code = @"<Код товара>";
firstItem.name = @"<Наименование товара>";
firstItem.unit = @"<Единица измерения>";
firstItem.vatMode = @"<Тип НДС>";
firstItem.price = @(<Цена за единицу>);
firstItem.quantity = @(<Количество единиц>);
firstItem.sum = @(<Цена>);
firstItem.vatAmount = @(<Размер НДС>);
firstItem.discountRate = @(<Скидка в процентах>);
firstItem.discountAmount = @(<Скидка в рублях (вкл. в стоимость)>);
RFIInvoiceItem *secondItem = [RFIInvoiceItem new];
secondItem.code = @"<Код товара>";
...
invoiceData.items = @[firstItem, secondItem];
paymentRequest.invoiceData = invoiceData;
Метод [RFIPayService paymentInit: successBlock: failure:] выполняется асинхронно. В случае, если ответ от Банка получен, выполняется successBlock, в противном - failure:
[payService paymentInit:paymentRequest successBlock:^(RFIPaymentResponse *response) {
// обработка ответа от Банка
} failure:^(NSDictionary *error) {
// обработка ошибки
}];
Если paymentResponse.hasErrors не содержит ошибок, получаем ID транзакции
NSString * transactionId = paymentResponse.transactionId;
NSString * status = paymentResponse.status;
NSString * help = paymentResponse.help;
if(paymentResponse.card3ds) {
//Обработка 3DS
}
Если 3-D secure требуется, то необходимо сделать POST запрос на адрес paymentResponse.card3ds.ACSUrl с параметрами:
PaReq - с значением paymentResponse.card3ds.PaReq
MD - с значением paymentResponse.card3ds.MD
TermUrl - URL обработчика, на вашем сайте. На него будет возвращён пользователь после прохождения 3DS авторизации
Для проверки прохождения 3DS авторизации следует вызвать POST запросом API https://partner.rficb.ru/alba/ack3ds/ , передав туда:
service_id;
tid или order_id;
emitent_response - данные, пришедшие от банка-эмитента в виде JSON-encoded словаря (Содержатся в paymentResponse.card3ds)
check - подпись запроса
version=2.0 - версия протокола
NSString * check = [RFISigner sign:@"строка для подписи"
url:@"URL куда отправляем запрос"
requestParams: @{}
secretKey: payService.secret];
Также есть возможность воспользоваться готовым termUrl, для этого достаточно указать:
https://secure.rficb.ru/acquire?sid=<ID-Сервиса>&oid=<ID-Транзакции>&op=pay
Или в случае тестовой оплаты:
https://test.rficb.ru/acquire?sid=<ID-Сервиса>&oid=<ID-Транзакции>&op=pay
Получение информации о транзакции. Метод [RFIPayService transactionDetails: successBlock: failure:] выполняется асинхронно. В случае, если ответ от Банка получен, выполняется successBlock, в противном - failure:
[payService transactionDetails: transactionId successBlock:^(RFIPaymentResponse *response) {
// обработка ответа от Банка
} failure:^(NSDictionary *error) {
// обработка ошибки
}];
Статус инициализации транзакции. success - успех
NSString * transactionStatus = transactionDetails.status;
Статус проведения платежа. open, error, payed, success
NSString * transactionPayStatus = transactionDetails.transactionStatus;
- (void) check3DSStatusForService: (NSString *) serviceId
orderId: (NSNumber *) orderId
emitentResponse: (NSDictionary *) emitentResponse
andSecretKey: (NSString *) secretKey
{
NSString *checkURL = @"https://partner.rficb.ru/alba/ack3ds";
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:emitentResponse
options:0
error:&error];
NSString *emitentResponseJSON;
emitentResponseJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSMutableDictionary *paymentParams = [NSMutableDictionary dictionaryWithDictionary:@{
@"service_id": serviceId,
@"tid": [orderId stringValue],
@"emitent_response": emitentResponseJSON,
@"version": @"2.0"
}];
RFIRestRequester *requester = [[RFIRestRequester alloc] init];
[requester request:checkURL andMethod:@"post" andParams: paymentParams andSecret:secretKey];
NSLog(@"Ответ 3ds: %@",requester.responseJSONData);
}
TransactionDetails details = service.transactionDetails(response.getSessionKey());
if (details.getStatus() == TransactionStatus.PAYED || details.getStatus() == TransactionStatus.SUCCESS) {
// транзакция оплачена
} else {
// транзакция не оплачена
}