# 대량발행 (Bulk API)

팝빌 대량발행은 고객사에서 접수받은 대량의 현금영수증을 분산하여 동시에 처리하는 기술로 대규모 현금영수증을 효율적으로 처리하는데 최적화 되어 처리 소요시간을 기존 대비 1/100 수준으로 단축이 가능합니다.

> 다수 가맹점의 현금영수증을 API 1회 호출로 한꺼번에 발행하기 위한 방법으로 GroupBulk API를 제공하고 있습니다.\
> 단, GroupBulk API 이용이 필요한 경우에는 팝빌과 사전협의 후 지원하고 있습니다. [\[연동문의\]](https://developers.popbill.com/customer-center/inquiry)

## 대량발행 vs 단건발행

![팝빌 현금영수증 Bulk 발행과 단건 발행의 처리방식 비교](https://developers.popbill.com/images/guide/introduction/cashbill/comparison-bulk-issue.webp)

| 발행건수 |  대량발행 |   단건발행  |
| :--: | :---: | :-----: |
|  1만  | 0.18분 |  0.39시간 |
|  10만 |  1.8분 |   4시간   |
|  25만 |  4.5분 |  9.4시간  |
|  50만 |  9.2분 |   19시간  |
| 100만 | 18.3분 | 1일 15시간 |

\* 대량발행(Bulk API) 처리 소요시간은 접수를 기준으로 측정되며, 발행은 팝빌 B/G 프로세스로 처리됩니다. (발행 소요시간 = 접수시간\*2.5)

## 프로세스

프로그램 공급사가 팝빌에 현금영수증을 대량으로 접수하면, 팝빌은 B/G에서 이를 순차적으로 비동기 처리하여 발행합니다. [\[BulkSubmit - 대량발행 접수\]](https://developers.popbill.com/api-reference/cashbill/api/issue#BulkSubmit)

**대량발행**

```mermaid
flowchart LR
    ReceiptFranchise("가맹점 접수")
    Receipted("접수성공")
    Issue("발행")
    Issued("발행완료 <br/> (300)")
    SendNTS{"국세청 전송"}
    SendFail("전송실패 <br/> (305)")
    SendSuccess("전송성공 <br/> (304)")

    ReceiptFranchise -- BulkSubmit <br> (대량발행 접수) --> Receipted
    Receipted --> Issue
    Issue -- 팝빌 B/G에서 순차 처리 --> Issued
    Issued --> SendNTS
    SendNTS --> SendFail
    SendNTS --> SendSuccess

    classDef invoicee stroke-width:1px,font-weight:bold;
    classDef popbill stroke-width:1px,font-weight:bold;

    class ReceiptFranchise,Issued,Receipted invoicee
    class Issue,SendNTS,SendFail,SendSuccess popbill
```

## 문서번호 관리체계

문서번호란 현금영수증의 중복 발행을 방지하고 내부 관리를 위해 프로그램 공급사가 직접 생성하고 할당하는 고유번호 입니다. Bulk 접수 단위로 제출아이디(submitID)를 할당하고, Bulk에 포함된 개별 현금영수증 단위로 문서번호를 할당합니다. 단, 한번 사용된 제출아이디는 재사용할 수 없습니다.

| 관리주체     | 유형       | 변수명        |  길이 | 설명                                                          |
| -------- | -------- | ---------- | :-: | ----------------------------------------------------------- |
| 프로그램 공급사 | 제출아이디    | submitID   |  36 | 접수 시점에 고객사에서 할당한 제출아이디                                      |
| 프로그램 공급사 | 공급자 문서번호 | mgtKey     |  24 | 문서 관리를 위해 파트너가 할당하는 식별번호 영문 대소문자, 숫자, 특수문자(’-’,’\_‘)만 이용 가능 |
| 팝빌       | 접수아이디    | receiptID  |  36 | 접수 시점에 팝빌에서 자동으로 할당                                         |
| 팝빌       | 국세청승인번호  | confirmNum |  9  | 현금영수증 발행 시점에 팝빌에서 자동으로 할당                                   |

> **동일한 국세청승인번호가 존재합니다. 중복하여 할당이 가능한가요?**\
> 같은 거래일자에는 국세청승인번호를 중복하여 할당하지 않으며, 다른 거래 일자에는 동일한 국세청승인번호로 할당될 수 있습니다.

## 상태확인

팝빌 Bulk API로 처리된 현금영수증 상태 확인을 위해 아래 2가지 방법을 지원합니다.\
Bulk API는 처리결과가 비동기로 응답되기 때문에 상태 변경 시점에 팝빌이 결과를 즉시 전송하는 ‘Webhook’ 방식을 권장합니다.

- **Webhook(Push)**\
  팝빌에서 현금영수증 상태가 변경된 시점에 프로그램 공급사가 지정한 Callback URL로 이벤트 전달 [\[Webhook\]](https://developers.popbill.com/api-reference/cashbill/webhook/introduction)

- **API(Polling)**\
  파트너가 주기적으로 API를 호출하여 상태 확인

**Webhook(Push)**

```mermaid
sequenceDiagram
    participant 가맹점
    participant Webhook Receiver
    participant POPBiLL

    가맹점->>POPBiLL: Callback URL 등록
    가맹점->>POPBiLL: BulkSubmit - 대량발행 접수
    POPBiLL-->>가맹점: receiptID(접수아이디) 반환
    POPBiLL->>POPBiLL: 현금영수증 <br> 대량 발행
    POPBiLL->>Webhook Receiver: Webhook 실행 <br> Event Type = "BULKRESULT"
    Webhook Receiver->>Webhook Receiver: 결과 업데이트
    loop 최대 500건씩 묶어서 웹훅으로 전달
        POPBiLL->>POPBiLL: 국세청 전송 처리 완료
        POPBiLL->>Webhook Receiver: Webhook 실행 <br> Event Type = "NTS" <br> stateCode = 304(전송성공) <br> stateCode = 305(전송실패)
        Webhook Receiver->>Webhook Receiver: 결과 업데이트
    end
```

**API(Polling)**

```mermaid
sequenceDiagram
    participant 가맹점
    participant POPBiLL

    가맹점->>POPBiLL: BulkSubmit - 대량발행 접수
    POPBiLL-->>가맹점: receiptID(접수아이디) 반환
    POPBiLL->>POPBiLL: 현금영수증 <br> 대량발행
    가맹점->>POPBiLL: GetBulkResult - 대량 접수결과 확인
    POPBiLL-->>가맹점: txState(접수상태) 반환 <br> 0: 접수 <br> 1: 처리중 <br> 2: 처리완료
    POPBiLL->>POPBiLL: 국세청 전송 및 결과반영
    가맹점->>POPBiLL: GetInfos - 다수건 상태 확인
    POPBiLL-->>가맹점: stateCode(상태코드) 반환 <br> stateCode = 304(전송성공) <br> stateCode = 305(전송실패)
    가맹점->>가맹점: 결과 업데이트
```
