B2BH2H

Как это работает

Сервис Платёжные поручения позволяет создавать рублёвые платёжные поручения для следующих кейсов:

  • Создание черновика рублёвого платёжного поручения.
  • Создание рублёвого платёжного поручения с подписью.
  • Создание черновика рублёвого платёжного поручения в бюджет.
  • Создание рублёвого платёжного поручения в бюджет с подписью.
Создание черновика рублёвого платёжного поручения

Для создания черновика рублёвого платёжного поручения необходимо выполнить запрос, не передавая параметр digestSignatures .

Создание черновика рублёвого платёжного поручения в бюджет

Для создания черновика рублёвого платёжного поручения в налоговую или бюджетные организации необходимо выполнить запрос, не передавая параметр digestSignatures .

Реквизиты налоговой или бюджетной организации передаются в объекте departmentalInfo . Обязательные поля для таких платежей приведены ниже.

BODY
Атрибут
Описание
objectrequired

Реквизиты налогового, таможенного или иного бюджетного платежа

uip
stringrequired

Уникальный идентификатор платежа/начисления

drawerStatus101
stringrequired

Статус плательщика

kbk
stringrequired

Код бюджетной классификации. Если кода нет, укажите значение 0

oktmo
stringrequired

Код OKTMO. Если кода нет, укажите значение 0

reasonCode106
stringrequired

Показатель основания платежа. Для налоговых и таможенных платежей указывать код обязательно, для остальных бюджетных платежей укажите значение 0

taxPeriod107
stringrequired

Налоговый период или код таможенного органа. Если показатель налогового периода отсуствует, то укажите значение 0

docNumber108
stringrequired

Номер налогового документа

docDate109
stringrequired

Дата налогового документа в формате YYYY-MM-DD. Если этого реквизита нет, то укажите значение 0

paymentKind110
stringoptional

Код выплат

Пример запроса для подписанного платёжного поручения в бюджет
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 .

Передача электронной подписи вместе с документом

Для передачи ЭП под документом используется массив digestSignatures , в котором передаются объекты типа Signature . Серийный номер сертификата certificateUuid заполняется значением поля serialNumber из ответа метода "Получение RSA-сертификата". При подписании УКЭП параметр certificateUuid не заполняется.

BODY
Атрибут
Описание
array of objectoptional

Электронные подписи по дайджесту документа

base64Encoded
stringrequired

Значение ЭП документа, закодированное в Base64

certificateUuid
stringoptional

Серийный номер сертификата, использованного при создании ЭП

Пример электронной подписи по дайджесту документа
1"digestSignatures": [
2    {
3        "base64Encoded": "HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w==",
4        "certificateUuid": "61000366d11e143acbc03a56d70001000366d1"
5    }
6]

Для платёжных поручений, создаваемых по собственным счетам, можно передать одну или две электронных подписи (или не передавать, если ЭП отсутствует) вместе с реквизитами создаваемого документа.

Если электронная подпись или подписи переданы в запросе, то они сохраняются вместе с документом, а сам документ продвигается дальше по своему жизненному циклу.

Если электронная подпись или подписи не были переданы, то документ сохраняется в своем начальном статусе и ожидает дальнейшего подписания в интерфейсе Альфа-Бизнес.

Подписание по алгоритму RSA

Для подписания может использоваться сертификат, выпущенный в Альфа-Бизнес, или сертификат, выпущенный при помощи сервиса Alfa API согласно разделу "Электронная подпись".

Требования к передаваемой электронной подписи:

  • формат подписи - PKCS#7 Attached;
  • алгоритм электронной подписи - sha256WithRSAEncryption.
Пример формирования RSA подписи
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) .

Подписание по алгоритму ГОСТ с использованием сертификата УКЭП

Для подписания может использоваться сертификат УКЭП, выпущенный любым аккредитованным УЦ. Если сертификат принадлежит лицу, обладающим правом подписи по уставу компании, то он самодостаточен. Если сертификат выпущен для уполномоченного лица, обладающего правом подписи по доверенности, то, помимо сертификата, потребуется выпустить машиночитаемую доверенность (МЧД).

Для регистрации выпущенной МЧД в Альфа-Банке используйте метод "Запрос на регистрацию МЧД в Банке".

Запрос на подписание реестра платежей должен быть отправлен от лица пользователя, который подписывал реестр (лицо, на чьё имя выпущен сертификат или зарегистрирована МЧД).

При подписании УКЭП допускается передача только одной подписи в массиве digestSignatures .

Формат дайджеста РПП

Digest (дайджест) – набор значимых полей платёжного документа, который подписывается электронной подписью (ЭП).

  • Необходимо использовать кодировку UTF-8.
  • Поля дайджеста должны быть отсортированы по алфавиту (от A до Z).
  • Значения сумм и комиссий в дайджесте и в запросе должны быть идентичны.
  • Если какое-то поле не заполняется и не передаётся в запросе, то его не требуется добавлять в дайджест.
  • Разделитель строк должен быть в формате unix (одиночный \n).
  • Последняя строка дайджеста не должна содержать перевод строки.

Сформированный дайджест перед подписанием должен быть закодирован в Base64.

Наименование поляОписаниеПример
amountСумма платежа1.01
dateДата составления документа2022-10-11
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
Пример дайджеста
1amount=1.01
2date=2022-10-11
3departmentalInfo.docNumber108=000000000000001
4departmentalInfo.drawerStatus101=01
5departmentalInfo.kbk=18210102010011000110
6departmentalInfo.oktmo=45902000
7departmentalInfo.reasonCode106=ТП
8departmentalInfo.uip=0
9externalId=22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6
10operationCode=01
11payeeAccount=40702810564564564531
12payeeBankBic=040173745
13payeeBankCorrAccount=30101810800000000745
14payeeInn=7723870785
15payeeKpp=553453453
16payeeName=Общество с ограниченной ответственностью "Получатель"
17payerAccount=40702810102300000001
18payerBankBic=044525593
19payerBankCorrAccount=30101810200000000593
20payerInn=0453438040
21payerKpp=046773311
22payerName=Общество с ограниченной ответственностью "Клиент"
23priority=5
24purpose=Оплата заказа №1. НДС не облагается