Сервис «Платёжные поручения» предоставляет возможность создания рублёвых платёжных поручений для следующих кейсов:
- •Создание черновика рублёвого платёжного поручения.
- •Создание рублёвого платёжного поручения с подписью.
- •Создание черновика рублёвого платёжного поручения в бюджет.
- •Создание рублёвого платёжного поручения в бюджет с подписью.
Создание черновика рублёвого платёжного поручения
Для создания черновика рублёвого платёжного поручения необходимо выполнить запрос, не передавая параметр digestSignatures
.
Создание черновика рублёвого платёжного поручения в бюджет
Для создания черновика рублёвого платёжного поручения в налоговую или бюджетные организации необходимо выполнить запрос, не передавая параметр digestSignatures
.
Реквизиты налоговой или бюджетной организации передаются в объекте departmentalInfo
. Обязательные поля для таких платежей приведены ниже.
Уникальный идентификатор платежа/начисления
Статус плательщика
Код бюджетной классификации. Если кода нет, укажите значение 0
Код OKTMO. Если кода нет, укажите значение 0
Показатель основания платежа. Для налоговых и таможенных платежей указывать код обязательно, для остальных бюджетных платежей укажите значение 0
Налоговый период или код таможенного органа. Если показатель налогового периода отсуствует, то укажите значение 0
Номер налогового документа
Дата налогового документа в формате YYYY-MM-DD. Если этого реквизита нет, то укажите значение 0
Код выплат
1{
2 "departmentalInfo": {
3 "uip": "0",
4 "drawerStatus101": "01",
5 "kbk": "18210102010011000110",
6 "oktmo": "45902000",
7 "reasonCode106": "ТП",
8 "taxPeriod107": "МС.02.2022",
9 "docNumber108": "000000000000001",
10 "docDate109": "2022-05-25"
11 }
12}
Создание рублёвого платёжного поручения с подписью
Для создания рублёвого платёжного поручения с подписью необходимо выполнить запрос, передавая в параметре digestSignatures
электронную подпись. Подробнее про формирование и передачу электронной подписи вместе с документом указано ниже.
Также становится обязательным к заполнению значение параметра payeeInn
.
Создание рублёвого платёжного поручения в бюджет с подписью
Для создания рублёвого платёжного поручения в налоговую или бюджетные организации необходимо выполнить запрос, передавая в параметре digestSignatures
электронную подпись. Подробнее про формирование и передачу электронной подписи вместе с документом указано ниже.
Также становится обязательным к заполнению значение параметра payeeInn
.
Реквизиты налоговой или бюджетной организации передаются в объекте departmentalInfo
.
Передача электронной подписи вместе с документом
Требования к передаваемой электронной подписи:
- •формат подписи - PKCS#7 Attached;
- •алгоритм электронной подписи - sha256WithRSAEncryption.
Для передачи ЭП под документом используется массив digestSignatures
, в котором передаются объекты типа Signature
. Серийный номер сертификата certificateUuid
заполняется значением поля serialNumber
из ответа метода "Получение RSA-сертификата".
Значение ЭП документа, закодированное в Base64
Серийный номер сертификата, использованного при создании ЭП
1"digestSignatures": [
2 {
3 "base64Encoded": "HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w==",
4 "certificateUuid": "61000366d11e143acbc03a56d70001000366d1"
5 }
6]
Для платёжных поручений, создаваемых по собственным счетам, можно передать одну или две электронных подписи (или не передавать, если ЭП отсутствует) вместе с реквизитами создаваемого документа.
Если электронная подпись или подписи переданы в запросе, то они сохраняются вместе с документом, а сам документ продвигается дальше по своему жизненному циклу.
Если электронная подпись или подписи не были переданы, то документ сохраняется в своем начальном статусе и ожидает дальнейшего подписания в интерфейсе Альфа-Бизнес.
Подписание по алгоритму RSA
Для подписания может использоваться сертификат, выпущенный в Альфа-Бизнес, или сертификат, выпущенный при помощи сервиса Alfa API согласно разделу "Электронная подпись".
1 public static String KEYSTORE_PATH = "";
2 public static String SIGNATURE_ALGORYTHM = "";
3 public static String KEYSTORE_PASSWORD = "";
4 public static String KEYSTORE_TYPE = "";
5 public static String KEYSTORE_ALIAS = "";
6
7 public static String signDataWithRSA(String dataToSign, String p12FileName)
8 throws KeyStoreException, OperatorCreationException, CertificateEncodingException, IOException, CMSException {
9
10 Security.addProvider(new BouncyCastleProvider());
11 BouncyCastleProvider provider = (BouncyCastleProvider) Security.getProvider("BC");
12
13 KeyStore keyStore = loadKeyStore(String.format(KEYSTORE_PATH, p12FileName));
14 X509Certificate certificate = getCertificate(keyStore);
15 X509CertificateHolder certificateHolder = new X509CertificateHolder(certificate.getEncoded());
16
17 CMSSignedDataGenerator signedDataGen = new CMSSignedDataGenerator();
18 ContentSigner signer = new JcaContentSignerBuilder(SIGNATURE_ALGORYTHM).setProvider(provider)
19 .build(getKey(keyStore));
20 signedDataGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
21 new JcaDigestCalculatorProviderBuilder().setProvider(provider).build())
22 .build(signer, certificateHolder));
23 signedDataGen.addCertificates(new JcaCertStore(List.of(certificate)));
24
25 CMSSignedData signedData = signedDataGen.generate(new CMSProcessableByteArray(dataToSign.getBytes()), false);
26 return new String(Base64.getEncoder().encode(signedData.getEncoded("DER")));
27 }
28
29 private static KeyStore loadKeyStore(String keystoreFilePath) throws KeyStoreException {
30 KeyStore keystore = KeyStore.getInstance(KEYSTORE_TYPE);
31 try (InputStream inputStream = new FileInputStream(keystoreFilePath)) {
32 keystore.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
33 } catch (IOException | NoSuchAlgorithmException | CertificateException e) {
34 throw new RuntimeException("Ошибка открытия хранилища ключей", e);
35 }
36 return keystore;
37 }
38
39 private static X509Certificate getCertificate(KeyStore keyStore) {
40 try {
41 return (X509Certificate) keyStore.getCertificate(KEYSTORE_ALIAS);
42 } catch (KeyStoreException e) {
43 throw new RuntimeException("Ошибка получения сертификата", e);
44 }
45 }
46
47 private static PrivateKey getKey(KeyStore keyStore) {
48 try {
49 return (PrivateKey) (keyStore.getKey(KEYSTORE_ALIAS, KEYSTORE_PASSWORD.toCharArray()));
50 } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) {
51 throw new RuntimeException("Ошибка получения закрытого ключа", e);
52 }
53 }
В качестве альтернативы можно использовать готовую реализацию, предоставляемую SDK для подписи. Для подписания платёжных поручений необходимо при создании экземпляра класса CmsSignatureService
задать кодировку передачи подписи, установив значение константы SignedDataEncoding.DER
.
1CmsSignatureService cmsSignatureService = new CmsSignatureServiceImpl(
2KeyStoreParameters.builder()
3 .path("/path/to/keystore")
4 .type(KeyStoreParameters.KeyStoreType.JKS)
5 .password("example")
6 .privateKey(PrivateKeyParameters.builder()
7 .alias("example")
8 .password("example")
9 .build())
10 .certificate(CertificateParameters.builder()
11 .alias("example")
12 .build())
13 .build(),
14 SignatureAlgorithm.RSA,
15 SignedDataEncoding.DER
16);
Во всех остальных аспектах процедура остаётся неизменной. Для подписания данных с использованием подкреплённой подписи воспользуйтесь методом signAttached(byte[] data)
.
Формат дайджеста РПП
Digest (дайджест) - набор значимых полей платёжного документа, который подписывается электронной подписью (ЭП).
- •Необходимо использовать кодировку UTF-8.
- •Поля дайджеста должны быть отсортированы по алфавиту (от A до Z).
- •Значения сумм и комиссий в дайджесте и в запросе должны быть идентичны.
- •Если какое-то поле не заполняется и не передается в запросе, то его не требуется добавлять в дайджест.
- •Разделитель строк должен быть в формате unix (одиночный \n).
- •Последняя строка дайджеста не должна содержать перевод строки.
Сформированный дайджест перед подписанием должен быть закодирован в Base64.
Наименование поля | Описание | Пример |
---|---|---|
amount | Сумма платежа | 1.01 |
date | Дата составления документа | 2018-05-31 |
departmentalInfo.docNumber108 | Номер налогового документа | 000000000000001 |
departmentalInfo.drawerStatus101 | Статус плательщика | 01 |
departmentalInfo.kbk | Код бюджетной классификации | 18210102010011000110 |
departmentalInfo.oktmo | Код ОКТМО | 45902000 |
departmentalInfo.paymentKind110 | Код выплат | 1 |
departmentalInfo.reasonCode106 | Показатель основания платежа | ТП |
departmentalInfo.uip | Уникальный идентификатор платежа | 0 |
externalId | Идентификатор документа, присвоенный сервисом | 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 |
incomeTypeCode | Код вида дохода получателей выплаты по 229-ФЗ | 2 |
operationCode | Код операции | 01 |
payeeAccount | Счёт получателя платежа | 40702810564564564531 |
payeeBankBic | БИК банка получателя платежа | 040173745 |
payeeBankCorrAccount | Корсчет банка получателя платежа | 30101810800000000745 |
payeeInn | ИНН получателя платежа | 7723870785 |
payeeKpp | КПП получателя платежа | 553453453 |
payeeName | Полное наименование получателя платежа | Общество с ограниченной ответственностью "Получатель" |
payerAccount | Счёт плательщика | 40702810600010800068 |
payerBankBic | БИК банка плательщика | 044525593 |
payerBankCorrAccount | Корсчёт банка плательщика | 30101810200000000593 |
payerInn | ИНН плательщика | 7728168971 |
payerKpp | КПП плательщика | 770801001 |
payerName | Полное наименование плательщика | Общество с ограниченной ответственностью "Клиент" |
priority | Очерёдность платежа | 5 |
purpose | Назначение платежа | Оплата заказа №1. НДС не облагается. |
1amount=1.01
2date=2018-05-31
3departmentalInfo.docNumber108=000000000000001
4departmentalInfo.drawerStatus101=01
5departmentalInfo.kbk=18210102010011000110
6departmentalInfo.oktmo=45902000
7departmentalInfo.paymentKind110=1
8departmentalInfo.reasonCode106=ТП
9departmentalInfo.uip=0
10externalId=22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6
11incomeTypeCode=2
12operationCode=01
13payeeAccount=40702810564564564531
14payeeBankBic=040173745
15payeeBankCorrAccount=30101810800000000745
16payeeInn=7723870785
17payeeKpp=553453453
18payeeName=Общество с ограниченной ответственностью "Получатель"
19payerAccount=40702810600010800068
20payerBankBic=044525593
21payerBankCorrAccount=30101810200000000593
22payerInn=7728168971
23payerKpp=770801001
24payerName=Общество с ограниченной ответственностью "Клиент"
25priority=5
26purpose=Оплата заказа №1. НДС не облагается.