External Integrations¶
Overview Diagram¶
graph LR
subgraph App["STORE by UtaTen"]
A["Order / Checkout"]
B["Webhook Handlers"]
C["Scheduled Jobs"]
D["Admin: CKC Import"]
E["Membership: CkcConnect"]
F["API: Address Lookup"]
G["Mail Notifications"]
end
A -->|"SBPS gateway redirect\nSHA-1 signed\nShift_JIS"| SBPS["SBPS\nSoftBank Payment"]
B -->|"webhook OK/NG"| SBPS
A -->|"Atone JS SDK\nSHA-256 HMAC"| ATONE["Atone\nNP後払い BNPL"]
B -->|"Np-Confirmation-Checksum"| ATONE
D -->|"ZIP serial code import\nlocal file only"| CKC_FILE["Chekicha\nserial code ZIPs"]
E -->|"HTTPS POST\napi.ckc.utaten.com"| CKC_API["Chekicha API"]
F -->|"Geocoding API\nssl_verify_peer=false"| GMAPS["Google Maps API"]
C -->|"SFTP + SSH key\nTSV"| ORICON["Oricon"]
C -->|"plain FTP\nfixed-width ASCII"| BILLBOARD["Billboard Japan"]
G -->|"SMTP / Mailgun"| MAIL["Mail Provider"]
SBPS (SoftBank Payment Service)¶
Purpose: Primary payment gateway — credit card (3D-Secure 2), docomo, au PAY, SoftBank, PayPay, UnionPay.
Trigger: POST /order/process for checkout; async POST /webhook/sbps for status updates.
Protocol:
- Outbound: SHA-1 signed form params (sps_hashcode), Shift_JIS encoded item_name, HTTP redirect to gateway URL
- Inbound webhook: plain-text OK, / NG, response expected; no inbound HMAC verification
- URLs env-switched: SBPS_GATEWAY_URL (prod) / test URL
Key files: app/Modules/Payment/Providers/Sbps/SbpsLinkService.php, app/Http/Controllers/Web/Webhook/SbpsPaymentController.php
Config env keys: SBPS_MERCHANT_ID, SBPS_SERVICE_ID, SBPS_HASH_KEY, SBPS_GATEWAY_URL
Failure: No SBPS → all normal purchases blocked. SBPS webhook lacks HMAC — replay attacks possible.
Atone (NP後払い / BNPL)¶
Purpose: Buy Now Pay Later / deferred payment via convenience store.
Trigger: Order confirmation page (JS SDK); POST /webhook/atone for authorization result.
Protocol:
- Outbound: AtoneChecksumService SHA-256 HMAC on ksort-ed params, base64 encoded; separate prod/test key pairs
- Inbound webhook: Np-Confirmation-Checksum header validated with hash_equals (timing-safe)
- Atone fulfilment is inline in OrderController::store() — synchronous, no redirect
Key files: app/Modules/Payment/AtoneChecksumService.php, app/Http/Controllers/Web/Webhook/AtoneWebhookController.php
Config env keys: ATONE_PUBLIC_KEY, ATONE_SECRET_KEY (prod + test variants)
Failure: No Atone → BNPL checkout path blocked; other payment methods unaffected.
Chekicha (CKC Platform)¶
Two distinct sub-flows:
Serial Code Import (Admin)¶
Purpose: Bulk-import digital serial codes for CKC products.
Trigger: Admin uploads ZIP file via product management UI.
Protocol:
- Local file processing only — no external API call
- UnzipSerialCodeAction → extracts to storage/app/private/tmp/ (spatie/temporary-directory)
- Fallback: shell_exec('unar ...') for non-standard ZIP encodings
- CSV files SJIS→UTF-8 converted, validated via ChekichaImport (Maatwebsite Excel)
- 6 validation rules: artist name, group name, code type, duplicate codes, valid-from/until dates
- Results → SerialCodeDTO → CkcCode::create()
Security note: UnzipSerialCodeAction::extractZipWithUnar calls shell_exec with uploaded file path. Currently safe (path from UploadedFile::path()), but watch for path traversal if this changes.
User Account Linking (CkcConnect)¶
Purpose: Link user's UtaTen account to external Chekicha fan platform after purchase.
Trigger: Order fulfilment (inside DB transaction), and /mypage/ckc_connect.
Protocol: HTTPS POST to api.ckc.utaten.com (prod) / develop.api.ckc.utaten.com (test)
Critical risk: CkcConnect::attach() is called inside the open DB transaction during order fulfilment. Network failure or Chekicha API downtime causes full order rollback.
Key files: app/Modules/Membership/Providers/CkcConnect.php, app/Modules/Chekicha/
Google Maps API¶
Purpose: Postcode → address lookup for checkout address form.
Trigger: GET /api/address?postcode=... → Api\AddressController.
Protocol: Geocoding API only. ssl_verify_peer = false in GoogleMapsService — TLS verification disabled.
Key files: app/Modules/Maps/Providers/GoogleMapsService.php, app/Http/Controllers/Api/AddressController.php
Config env key: GOOGLE_MAPS_API_KEY
Failure: Returns null on non-OK status; address form falls back to manual entry.
Security note: ssl_verify_peer = false disables certificate validation — MITM risk on Google Maps API calls.
Oricon (Music Chart Reporting)¶
Purpose: Daily automated sales reporting to Oricon chart agency.
Trigger: Scheduled job SendToOricon daily 22:00 JST.
Protocol: SFTP with SSH key authentication to oricon-sftp disk; TSV file generated via Maatwebsite Excel (OriconTsvExport); shipping window 00:00–21:59.
Key files: app/Modules/Order/Jobs/SendToOricon.php, app/Modules/Order/Exports/OriconTsvExport.php
Config: config/filesystems.php → oricon-sftp disk (host, username, SSH private key, passphrase)
Failure: Throwable caught and swallowed — failures are silent. No alert, no retry. Oricon receives stale/missing data without any notification.
Billboard Japan (Music Chart Reporting)¶
Purpose: Daily automated sales reporting to Billboard Japan.
Trigger: Scheduled job SendToBillboard daily 22:00 JST.
Protocol: Plain FTP (no TLS/SFTP) to billboard-ftp disk; fixed-width ASCII \r\n format; hardcoded chain code 9650 / store code 557001; quantities >99,999 split across rows.
Key files: app/Modules/Order/Jobs/SendToBillboard.php
Config: config/filesystems.php → billboard-ftp disk (host, username, password)
Security note: Plain FTP transmits credentials and data in cleartext.
Failure: No try/catch — exceptions propagate, job fails and retries per queue config.
Mail¶
Purpose: All transactional email — registration, order confirmation, shipment, lottery results, inquiry.
Trigger: Laravel notification dispatch (9 notification/mailable classes).
Protocol: SMTP or Mailgun via config/mail.php.
Key notifications:
- Membership: RegisterNotification, ResetPasswordNotification, VerifyEmailNotification
- Order: OrderFinishNotification, ShipmentNotification
- Lottery: LotteryAppliedNotification, LotteryUpdatedNotification, LotteryWonNotification
- Inquiry: InquiryAutoReply, InquiryNotification
Failure: Queue worker down → notifications accumulate. InquirySentListener uses sync Mail::send() — inquiry form errors on mail failure.
Critical Dependency Map¶
| Service Down | Impact |
|---|---|
| SBPS | All normal purchases blocked |
| Atone | BNPL purchases blocked only |
| Chekicha API | Order fulfilment rolls back (DB transaction) |
| Google Maps | Address autocomplete unavailable; manual entry still works |
| Oricon SFTP | Silent failure — chart reporting gap, no alert |
| Billboard FTP | Job fails + retries — chart reporting delayed |
| Mail provider | Queued notifications accumulate; inquiry form errors |