From 0eb17e6a7f39a1cb86c543d361c863c9b4a85b77 Mon Sep 17 00:00:00 2001 From: shamanov_d Date: Mon, 16 Jun 2025 21:03:56 +0300 Subject: [PATCH 1/2] url2 --- src/Robokassa.spec.ts | 53 ++++++++++++------- .../calculateSendingSignatureValue.spec.ts | 18 +++++++ .../calculateSendingSignatureValue.ts | 5 ++ src/types/IRobokassaOrder.ts | 26 +++++++++ 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/Robokassa.spec.ts b/src/Robokassa.spec.ts index 5716ed1..8c62a73 100644 --- a/src/Robokassa.spec.ts +++ b/src/Robokassa.spec.ts @@ -17,24 +17,24 @@ describe('#Robokassa', () => { }); }); - it('can be initialized with custom values', () => { - const result = new Robokassa({ - merchantLogin: 'my_merchant_login', - password1: 'my_password1', - password2: 'my_password2', - hashAlgorithm: 'sha256', - isTest: true, - url: 'https://test.robokassa.ru/CUSTOM_URL', - }); - expect(result.options).toEqual({ - merchantLogin: 'my_merchant_login', - password1: 'my_password1', - password2: 'my_password2', - hashAlgorithm: 'sha256', - url: 'https://test.robokassa.ru/CUSTOM_URL', - isTest: true, - }); - }); + // it('can be initialized with custom values', () => { + // const result = new Robokassa({ + // merchantLogin: 'my_merchant_login', + // password1: 'my_password1', + // password2: 'my_password2', + // hashAlgorithm: 'sha256', + // isTest: true, + // url: 'https://test.robokassa.ru/CUSTOM_URL', + // }); + // expect(result.options).toEqual({ + // merchantLogin: 'my_merchant_login', + // password1: 'my_password1', + // password2: 'my_password2', + // hashAlgorithm: 'sha256', + // url: 'https://test.robokassa.ru/CUSTOM_URL', + // isTest: true, + // }); + // }); describe(' ', () => { let robokassa: Robokassa; @@ -47,6 +47,23 @@ describe('#Robokassa', () => { }); }); + it('should pass InvId=0 when invId is not specified', () => { + const result = robokassa.generatePaymentUrl({ + description: 'Товар 1', + outSum: '100.00', + + resultUrl2: 'https://result.robokassa.ru', + successUrl2: 'https://success.robokassa.ru', + successUrl2Method: 'GET', + failUrl2: 'https://fail.robokassa.ru', + failUrl2Method: 'GET', + }); + + expect(result).toEqual( + 'https://auth.robokassa.ru/Merchant/Index.aspx?MerchantLogin=my_merchant_login&Description=%D0%A2%D0%BE%D0%B2%D0%B0%D1%80%201&OutSum=100.00&ResultUrl2=https%3A%2F%2Fresult.robokassa.ru&SuccessUrl2=https%3A%2F%2Fsuccess.robokassa.ru&SuccessUrl2Method=GET&FailUrl2=https%3A%2F%2Ffail.robokassa.ru&FailUrl2Method=GET&InvId=0&SignatureValue=0fde8eb3057dabcdf1597ddcfcce35cd', + ); + }); + describe('#generatePaymentUrl', () => { it('should generate url with minimum parameters', () => { const result = robokassa.generatePaymentUrl({ diff --git a/src/internal/calculateSendingSignatureValue.spec.ts b/src/internal/calculateSendingSignatureValue.spec.ts index 2df867e..4aaa6c8 100644 --- a/src/internal/calculateSendingSignatureValue.spec.ts +++ b/src/internal/calculateSendingSignatureValue.spec.ts @@ -18,6 +18,24 @@ describe('#calculateSendingSignatureValue', () => { expect(result).toEqual('my_merchant_login:100.00:42:my_password1'); }); + it('should build string WITH additional parameters', () => { + const result = buildSendingSignatureString({ + password1: 'my_password1', + merchantLogin: 'my_merchant_login', + order: { + description: 'my_description', + outSum: '100.00', + resultUrl2: 'my_result_url2', + successUrl2: 'my_success_url2', + successUrl2Method: 'GET', + failUrl2: 'my_fail_url2', + failUrl2Method: 'GET', + }, + }); + + expect(result).toEqual('my_merchant_login:100.00:my_result_url2:my_success_url2:GET:my_fail_url2:GET:my_password1'); + }); + it('should build string WITH sorted user parameters', () => { const result = buildSendingSignatureString({ password1: 'my_password1', diff --git a/src/internal/calculateSendingSignatureValue.ts b/src/internal/calculateSendingSignatureValue.ts index ff834ee..4dcef43 100644 --- a/src/internal/calculateSendingSignatureValue.ts +++ b/src/internal/calculateSendingSignatureValue.ts @@ -24,6 +24,11 @@ export const buildSendingSignatureString = ({ order.outSumCurrency, order.userIp, order.receipt ? JSON.stringify(order.receipt) : undefined, + order.resultUrl2, + order.successUrl2, + order.successUrl2Method, + order.failUrl2, + order.failUrl2Method, password1, ...signatureUserParams, ]; diff --git a/src/types/IRobokassaOrder.ts b/src/types/IRobokassaOrder.ts index f7473d9..c742bd9 100644 --- a/src/types/IRobokassaOrder.ts +++ b/src/types/IRobokassaOrder.ts @@ -1,6 +1,8 @@ import { IRobokassaReceipt } from './IRobokassaReceipt'; import { RobokassaUserParameterKey } from './RobokassaUserParameterKey'; +type Method = 'GET' | 'POST'; + export interface IRobokassaOrder { /*** Описание покупки, можно использовать только символы английского или русского алфавита, цифры и знаки препинания. @@ -150,4 +152,28 @@ export interface IRobokassaOrder { */ previousInvoiceId?: number; + + /** + * Дополнительное оповещение об успешной оплате позволяет получить уведомление на альтернативный адрес, отличный от указанного в настройках магазина(Result URL). + * Для операций с холдами на этот адрес направляется уведомление об успешной предавторизации, и это единственный способ его получить. + * + * https://docs.robokassa.ru/pay-interface/#notification + */ + resultUrl2?: string; + + /** + * Дополнительная возможность переадресации покупателя после успешной оплаты на адрес отличный от Success URL указанный в настройках магазина. + * + * https://docs.robokassa.ru/pay-interface/#return + */ + successUrl2?: string; + successUrl2Method?: Method; + + /** + * Дополнительная возможность переадресации покупателя после неуспешной оплаты на адрес отличный от Fail URL указанный в настройках магазина. + * + * https://docs.robokassa.ru/pay-interface/#return + */ + failUrl2?: string; + failUrl2Method?: Method; } From 925a578ad622b48ed80d098b09c5c47a067319f4 Mon Sep 17 00:00:00 2001 From: shamanov_d Date: Mon, 16 Jun 2025 21:10:06 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20Robokassa=20=D1=81=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=D1=81=D0=BA=D0=B8=D0=BC=D0=B8=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8=20=D0=B8=20=D1=83=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D1=88=D0=B5=D0=BD=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B8=20=D0=B2=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=B5=20IRobokassaOr?= =?UTF-8?q?der?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Robokassa.spec.ts | 36 +++++++++---------- .../calculateSendingSignatureValue.spec.ts | 4 ++- src/types/IRobokassaOrder.ts | 6 ++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/Robokassa.spec.ts b/src/Robokassa.spec.ts index 8c62a73..3c0733b 100644 --- a/src/Robokassa.spec.ts +++ b/src/Robokassa.spec.ts @@ -17,24 +17,24 @@ describe('#Robokassa', () => { }); }); - // it('can be initialized with custom values', () => { - // const result = new Robokassa({ - // merchantLogin: 'my_merchant_login', - // password1: 'my_password1', - // password2: 'my_password2', - // hashAlgorithm: 'sha256', - // isTest: true, - // url: 'https://test.robokassa.ru/CUSTOM_URL', - // }); - // expect(result.options).toEqual({ - // merchantLogin: 'my_merchant_login', - // password1: 'my_password1', - // password2: 'my_password2', - // hashAlgorithm: 'sha256', - // url: 'https://test.robokassa.ru/CUSTOM_URL', - // isTest: true, - // }); - // }); + it('can be initialized with custom values', () => { + const result = new Robokassa({ + merchantLogin: 'my_merchant_login', + password1: 'my_password1', + password2: 'my_password2', + hashAlgorithm: 'sha256', + isTest: true, + url: 'https://test.robokassa.ru/CUSTOM_URL', + }); + expect(result.options).toEqual({ + merchantLogin: 'my_merchant_login', + password1: 'my_password1', + password2: 'my_password2', + hashAlgorithm: 'sha256', + url: 'https://test.robokassa.ru/CUSTOM_URL', + isTest: true, + }); + }); describe(' ', () => { let robokassa: Robokassa; diff --git a/src/internal/calculateSendingSignatureValue.spec.ts b/src/internal/calculateSendingSignatureValue.spec.ts index 4aaa6c8..c0a4866 100644 --- a/src/internal/calculateSendingSignatureValue.spec.ts +++ b/src/internal/calculateSendingSignatureValue.spec.ts @@ -33,7 +33,9 @@ describe('#calculateSendingSignatureValue', () => { }, }); - expect(result).toEqual('my_merchant_login:100.00:my_result_url2:my_success_url2:GET:my_fail_url2:GET:my_password1'); + expect(result).toEqual( + 'my_merchant_login:100.00:my_result_url2:my_success_url2:GET:my_fail_url2:GET:my_password1', + ); }); it('should build string WITH sorted user parameters', () => { diff --git a/src/types/IRobokassaOrder.ts b/src/types/IRobokassaOrder.ts index c742bd9..c65a2b5 100644 --- a/src/types/IRobokassaOrder.ts +++ b/src/types/IRobokassaOrder.ts @@ -156,14 +156,14 @@ export interface IRobokassaOrder { /** * Дополнительное оповещение об успешной оплате позволяет получить уведомление на альтернативный адрес, отличный от указанного в настройках магазина(Result URL). * Для операций с холдами на этот адрес направляется уведомление об успешной предавторизации, и это единственный способ его получить. - * + * * https://docs.robokassa.ru/pay-interface/#notification */ resultUrl2?: string; /** * Дополнительная возможность переадресации покупателя после успешной оплаты на адрес отличный от Success URL указанный в настройках магазина. - * + * * https://docs.robokassa.ru/pay-interface/#return */ successUrl2?: string; @@ -171,7 +171,7 @@ export interface IRobokassaOrder { /** * Дополнительная возможность переадресации покупателя после неуспешной оплаты на адрес отличный от Fail URL указанный в настройках магазина. - * + * * https://docs.robokassa.ru/pay-interface/#return */ failUrl2?: string;