B2BH2H

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

Сервис Реестры платежей позволяет отправлять до пяти тысяч платёжных поручений в одном реестре. Это упрощает учёт платежей в адрес разных получателей: на свои счета, счета контрагентов - физических лиц и организаций.

Механизм отправки реестра платежей
1

Создайте реестр рублёвых платежей

2

Отправьте реестр платежей на подпись

Метод «Изменение статуса реестра платежей». В параметре тела запроса status необходимо передать значение ON_SIGNING - на подпись. В ответе метода в параметре content вы получите набор значимых полей документа в base64, который далее необходимо будет подписать электронной подписью.

3

Создайте запрос на подписание реестра платежей

Подпишите полученный на предыдущем шаге набор значимых полей документа RSA-сертификатом или УКЭП. Как сформировать подпись, описано в подразделе ниже.

Далее полученную подпись необходимо закодировать в base64 и передать в параметре base64Encoded массива digestSignatures метода «Создание запроса на подписание реестра платежей».

4

Получите результат наложения подписи

Метод «Получение результата наложения подписей». В параметре signatureId необходимо передать идентификатор запроса на подписание, полученный в ответе метода «Создание запроса на подписание реестра платежей».

При успешном подписании в ответе метода вернётся статус подписания SIGNED , после чего можно будет переходить в следующему шагу.

Если метод вернул статус подписания PARTIALLY_SIGNED , это означает, что переданных подписей недостаточно, либо только часть подписей из запроса была успешно наложена, и вам необходимо повторно создать запрос на подписание реестра платежей (шаг 3), передав подпись недостающего подписанта / исправленную подпись, после чего снова проверить статус подписания.

5

Отправьте реестр платежей на исполнение

После успешного наложения подписей необходимо отправить реестр платежей на исполнение, используя метод «Изменение статуса реестра платежей». В теле запроса в параметре status необходимо передать значение PROCESSING - на обработке.

6

Получите статус реестра платежей

Формирование и передача подписи реестра платежей

Для подписания реестра рублёвых платежей на шаге 3 необходимо сформировать подпись и передать её в методе «Создание запроса на подписание реестра платежей» в параметре digestSignatures .

Подписывать необходимо набор значимых полей платёжного документа, который возвращается в параметре content в ответе от метода «Изменение статуса реестра платежей» на шаге 2 инструкции, при переводе реестра в статус «На подпись».

Для передачи подписи используется массив digestSignatures тела запроса со следующей структурой объектов массива:

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

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

base64Encoded
stringrequired

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

certificateUuid
stringoptional
signatureType
stringrequired

Тип электронной подписи (RSA или УКЭП)

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

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

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

  • •
    формат подписи - PKCS#7 Attached;
  • •
    алгоритм электронной подписи - sha256WithRSAEncryption.

При подписании по алгоритму RSA можно передать одну или несколько электронных подписей.

Пример формирования 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 .

Для подписания данных с использованием подкреплённой подписи воспользуйтесь методом signAttached(byte[] data) .

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);
Подписание по алгоритму ГОСТ

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

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

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