OutlinePay APIOutlinePay API
OutlinePay is a processor-agnostic payments API for merchant platforms looking to offer US payments. We provide headless capabilities for merchant management, checkout pages, payment links, refunds, disputes, and event webhooks. OutlinePay는 미국 결제를 제공하려는 가맹점 플랫폼을 위한, 결제 처리사에 종속되지 않는 결제 API입니다. 가맹점 관리, 체크아웃 페이지, 결제 링크, 환불, 분쟁, 이벤트 웹훅을 헤드리스 방식으로 제공합니다.
Prefer tooling? Download the OpenAPI spec and import it into Postman, Insomnia, or a client generator.도구를 선호하시나요? OpenAPI 명세를 내려받아 Postman, Insomnia 또는 클라이언트 생성기에 가져오세요.
/v1 is still hardening. Until live keys are issued a change to behavior you rely on can still ship, always dated and labeled in the Changelog. Stability is the full rule./v1은 아직 다듬는 중입니다. 라이브 키가 발급되기 전까지는 의존하고 계신 동작을 바꾸는 변경이 배포될 수 있으며, 모든 변경은 변경 사항에 날짜와 라벨과 함께 기록됩니다. 전체 규칙은 안정성에 있습니다.
Conventions규약
Requests요청
Authentication인증
Authenticate every request with your partner secret key as a Bearer token. Keys come in test (olp_sk_test_…) and live (olp_sk_live_…) variants over the same API. Each is shown once at creation and stored hashed.모든 요청은 파트너 시크릿 키를 Bearer 토큰으로 사용해 인증합니다. 키는 동일한 API에서 테스트용(olp_sk_test_…)과 라이브용(olp_sk_live_…) 두 종류로 발급되며, 각 키는 생성 시 한 번만 표시되고 해시된 형태로 저장됩니다.
Authorization: Bearer olp_sk_test_YOUR_KEY
Errors오류
Errors return a matching HTTP status and a JSON body of two keys: code classifies the refusal, and details describes it, one entry per problem found.오류가 발생하면 해당하는 HTTP 상태 코드와 함께 두 개의 키로 이루어진 JSON 본문을 반환합니다. code는 거부의 종류를 나타내고, details는 발견된 문제를 항목 하나당 하나씩 담습니다.
{ "error": { "code": "not_found", "details": [
{ "param": "merchant_id", "message": "No such merchant: \"mrc_bogus\"." }
] } }
- Codes코드
- invalid_request (400), not_found (404 or 400, see below), authentication_error (401), merchant_not_onboarded (409), merchant_terms_not_accepted (409), idempotency_conflict (409), rate_limited (429), processor_error (502).invalid_request (400), not_found (404 또는 400, 아래 참조), authentication_error (401), merchant_not_onboarded (409), merchant_terms_not_accepted (409), idempotency_conflict (409), rate_limited (429), processor_error (502).
- details
- Never empty, and every entry carries a message. A refusal is a single entry everywhere except write-time validation, where each refused field is its own entry: unknown fields first, then value checks, in this reference's field order. Every entry shares the top-level code. A response without error.details did not come from the API. Treat it as a transient system error and retry.항상 1건 이상이며, 모든 항목에 message가 담깁니다. 저장 시점 검증을 제외한 모든 거부는 항목이 1건입니다. 저장 시점 검증에서는 거부된 필드마다 항목이 하나씩 생기며, 문서에 없는 필드가 먼저, 값 검사가 그 뒤에, 이 문서의 필드 순서대로 정렬됩니다. 모든 항목은 최상위 code와 같은 코드를 공유합니다. error.details가 없는 응답은 API가 생성한 것이 아닙니다. 일시적인 시스템 오류로 간주하고 재시도해 주십시오.
- 404 or 400404와 400의 구분
- An id that names nothing always carries not_found, and the status says where you put it: 404 in the path, 400 as a query parameter or a body field.아무것도 가리키지 않는 id는 언제나 not_found 코드를 담으며, HTTP 상태는 그 id를 어디에 두셨는지를 알려드립니다. 경로에 있으면 404, 쿼리 파라미터나 본문 필드로 전달하신 경우에는 400입니다.
- Malformed values형식이 잘못된 값
- A value we cannot accept at all, rather than one we looked up and could not find, is invalid_request with a 400. Both kinds quote the offending value back and name its field in the entry's param. A value the processor refuses when we forward it answers the same way, with the processor's own sentence in the entry's processor_message.조회해 보았으나 찾지 못한 값이 아니라 애초에 받을 수 없는 값은 invalid_request와 400으로 응답합니다. 두 경우 모두 문제가 된 값을 그대로 인용해 돌려드리고, 해당 필드 이름을 항목의 param에 담습니다. 전달한 값을 결제 처리사가 거부한 경우에도 같은 방식으로 응답하며, 처리사 자신의 설명이 항목의 processor_message에 담깁니다.
- Unknown parameters문서에 없는 파라미터
- A parameter an endpoint does not document is refused, not ignored. The refusal names the nearest parameter that endpoint does take, when there is one. Keys inside a documented object and metadata are not checked.해당 엔드포인트가 문서화하지 않은 파라미터는 무시하지 않고 거부합니다. 거부 응답에는 해당 엔드포인트가 받는 파라미터 중 가장 가까운 이름이 있으면 함께 담깁니다. 문서화된 객체 안의 키와 metadata는 검사하지 않습니다.
- param
- Present on an entry about exactly one request field: that field's name, in the API's spelling.정확히 하나의 요청 필드가 원인인 항목에 포함됩니다. API 표기 그대로의 해당 필드 이름입니다.
- doc_url
- Present on an entry when the fix is a different call than the one that failed: a link to the section here that explains it.실패한 호출과 다른 호출로 해결해야 할 때 항목에 포함됩니다. 해당 내용을 설명하는 이 문서의 섹션으로 바로 연결되는 링크입니다.
Idempotency멱등성
Send an Idempotency-Key header on any POST to make retries safe: two attempts carrying the same key are the same operation, however far apart they arrive. Optional everywhere except Create a refund, where it is required.재시도를 안전하게 하시려면 POST 요청에 Idempotency-Key 헤더를 보내십시오. 같은 키를 가진 두 요청은 시간이 아무리 벌어져도 같은 작업으로 처리됩니다. 환불 생성에서는 필수이며, 그 외의 모든 엔드포인트에서는 선택입니다.
- Generating a key키 생성 방법
- Any unique string. A UUID v4 is the usual choice. Mint it when the business action is created in your system (the order, the refund your support tool records), store it on that action, and send the same key on every retry of it. Two separate $5 refunds are two actions, so they carry two keys. A fresh key per HTTP attempt defeats the mechanism.고유한 문자열이면 어떤 값이든 되며, 보통 UUID v4를 사용합니다. 귀사 시스템에서 해당 업무 작업(주문, 상담 도구가 기록한 환불 건)이 만들어질 때 키를 발급해 그 작업에 저장해 두시고, 그 작업을 재시도할 때마다 같은 키를 보내 주십시오. 서로 다른 5달러 환불 두 건은 별개의 작업이므로 키도 두 개입니다. HTTP 시도마다 새 키를 발급하시면 이 장치가 무력화됩니다.
- What a retry gets재시도가 받는 응답
- The same key with the same body replays the stored response, status and all. Nothing executes twice.같은 키에 같은 본문이면 상태 코드까지 포함해 저장된 응답을 그대로 재생합니다. 어떤 것도 두 번 실행되지 않습니다.
- Conflicts충돌
- The same key with a different body is refused with 409 idempotency_conflict, and so is a retry that arrives while the first attempt is still running.같은 키에 다른 본문이면 409 idempotency_conflict로 거부됩니다. 첫 시도가 아직 실행 중일 때 도착한 재시도도 마찬가지입니다.
- Server errors서버 오류
- A 5xx response is not stored, so retrying after one executes fresh rather than replaying the failure.5xx 응답은 저장되지 않으므로, 서버 오류 후의 재시도는 실패를 재생하는 대신 새로 실행됩니다.
- Scope and lifetime범위와 유효 기간
- Keys are scoped to your account and to the key's mode, so the same string in test and live never collides. They are kept for 24 hours. After that, reusing the string starts a new request.키는 귀사 계정과 키의 모드 단위로 관리되므로, 같은 문자열이라도 테스트와 라이브에서 충돌하지 않습니다. 24시간 보관되며, 그 이후에 같은 문자열을 다시 사용하시면 새 요청으로 처리됩니다.
PHP has no built-in UUID function, and none is needed:PHP에는 UUID 생성 함수가 내장되어 있지 않지만, 별도의 라이브러리는 필요하지 않습니다.
<?php // Any unique string works. 32 random hex characters, no library needed: $key = bin2hex(random_bytes(16)); // Or the same entropy shaped as a standard UUID v4, if you prefer that: function uuid_v4(): string { $b = random_bytes(16); $b[6] = chr((ord($b[6]) & 0x0f) | 0x40); // version $b[8] = chr((ord($b[8]) & 0x3f) | 0x80); // variant return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($b), 4)); }
# Shells have one already, for a key you are sending by hand.
uuidgen
Pagination페이지네이션
List endpoints are cursor-based and newest-first. Pass limit (1–100, default 20) and starting_after=<id>. Responses are { "data": [...], "has_more": bool }.목록 엔드포인트는 커서 기반이며 최신순으로 반환합니다. limit(1~100, 기본값 20)과 starting_after=<id>를 전달하십시오. 응답 형식은 { "data": [...], "has_more": bool }입니다.
- Walking a list목록 순회 방법
- Send the id of the last object you received as the next starting_after, and stop when has_more comes back false.직전에 받으신 마지막 객체의 id를 다음 starting_after로 전달하시고, has_more가 false로 오면 중단하십시오.
- limit
- One we cannot read as an integer is refused. One outside 1–100 is clamped instead, so limit=500 returns 100 rather than an error.정수로 읽을 수 없는 값은 거부됩니다. 1~100을 벗어난 값은 거부하지 않고 범위 안으로 조정하므로, limit=500은 오류가 아니라 100건을 반환합니다.
- starting_after
- A cursor that names nothing is a 400 with not_found, like any other unknown id. It resolves against the request's own filters, so pairing it with a filter that excludes it is refused the same way.아무것도 가리키지 않는 커서는 다른 알 수 없는 id와 마찬가지로 not_found 코드와 함께 400으로 응답합니다. 커서는 해당 요청의 필터와 함께 조회되므로, 커서가 가리키는 객체를 제외하는 필터와 함께 전달하시면 동일하게 거부됩니다.
Rate limits요청 한도
Requests are limited per API key: currently 100 reads and 60 writes per minute.요청은 API 키별로 제한되며, 현재 분당 읽기 100회, 쓰기 60회입니다.
Over the limit, requests return 429 rate_limited with a Retry-After header (in seconds) and nothing is processed. Wait that long and retry the same call.한도를 초과하면 429 rate_limited와 함께 Retry-After 헤더(초 단위)가 반환되며 아무것도 처리되지 않습니다. 해당 시간만큼 기다리신 뒤 같은 호출을 다시 시도해 주십시오.
Amounts, timestamps & ids금액 · 시각 · 식별자
- Amounts are integers in the currency's minor unit: 10000 is $100.00 in USD.금액은 해당 통화의 최소 단위 정수입니다. 예를 들어 USD에서 10000은 $100.00입니다.
- Timestamps are ISO 8601 UTC strings.시각은 ISO 8601 UTC 문자열입니다.
- Ids are prefixed and opaque (pay_, link_, re_, mrc_, dp_, we_, evt_). Their length and prefix can change, so store them as text and do not parse them. Numeric ids never appear.ID는 접두사가 붙은 불투명한 값입니다(pay_, link_, re_, mrc_, dp_, we_, evt_). 길이와 접두사는 바뀔 수 있으므로 문자열로 저장하시고 파싱하지 마십시오. 숫자 ID는 노출되지 않습니다.
- Every resource names its type in object ("payment", "merchant", ...), which is also how an event's data says what it carries.모든 리소스는 object 필드로 자신의 타입을 밝힙니다("payment", "merchant" 등). 이벤트의 data가 무엇을 담고 있는지도 이 필드로 알 수 있습니다.
Stability안정성
/v1 is a namespace, not a version number. A change to how an endpoint behaves is dated in the Changelog rather than announced by a new path. If a /v2 ever appears it will be because the conventions on this page changed, and /v1 will keep working beside it./v1은 버전 번호가 아니라 네임스페이스입니다. 엔드포인트의 동작이 바뀌는 변경은 새 경로로 알려드리지 않고 변경 사항에 날짜와 함께 기록합니다. 언젠가 /v2가 생긴다면 그것은 이 페이지의 규약 자체가 바뀌었기 때문이며, 그때에도 /v1은 그 옆에서 계속 동작합니다.
These are additive and arrive in any release:다음은 기존 동작에 더해지는 변경이며, 어느 배포에서나 도착할 수 있습니다.
- A new endpoint.새로운 엔드포인트.
- A new optional parameter on an existing request.기존 요청에 추가되는 선택 파라미터.
- A new field on an existing response object.기존 응답 객체에 추가되는 필드.
- A new event type.새로운 이벤트 타입.
- A new value in an enum you already read, such as a payment status or an error code.이미 읽고 계신 열거값에 추가되는 값. 예를 들어 새로운 결제 상태나 오류 코드입니다.
- What that asks of you연동에 필요한 것
- Ignore fields you do not recognize rather than failing on them. Treat an unfamiliar enum value as one you do not handle yet, not as invalid data. Match the error codes you handle and let the rest fall to a default.알지 못하는 필드는 오류로 처리하지 마시고 무시하십시오. 처음 보는 열거값은 잘못된 데이터가 아니라 아직 처리하지 않는 값으로 다루십시오. 처리하시는 오류 코드만 분기하시고 나머지는 기본 처리로 넘기십시오.
- Changes to behavior you rely on의존하고 계신 동작의 변경
- Renaming or removing a field, changing its type, changing what a value means, changing the status or error code for a request that has not changed, or removing an endpoint, an event type or an enum value. Each one is dated in the Changelog and carries one of the two labels below.필드의 이름 변경 또는 삭제, 필드 타입 변경, 값의 의미 변경, 동일한 요청에 대한 상태 코드나 오류 코드 변경, 엔드포인트와 이벤트 타입과 열거값의 삭제입니다. 각 변경은 변경 사항에 날짜와 함께 기록되며 아래 두 라벨 중 하나가 붙습니다.
- Breaking
- A documented request whose answer we changed. customer_email became customer.email, so an integration reading the old field reads nothing.문서에 있던 요청의 응답이 바뀐 변경입니다. customer_email이 customer.email이 되었으므로, 이전 필드를 읽던 연동은 아무것도 읽지 못합니다.
- Stricter
- Input we never documented and no longer accept, where it used to be ignored or answered misleadingly. limit=abc used to return a single row and is now refused. Code that sent only documented values is unaffected.문서에 없던 입력을 더 이상 받지 않는 변경입니다. 이전에는 무시되거나 오해를 부르는 응답을 받던 값입니다. limit=abc는 이전에 한 건을 반환했으나 이제는 거부됩니다. 문서에 있는 값만 보내신 코드는 영향을 받지 않습니다.
- Current status현재 상태
- Until live keys are issued, a change to behavior you rely on can ship, labeled as above. At go-live /v1 freezes, and after that such a change ships only as a dated version you choose to move to. An integration that does nothing keeps the behavior it was written against.라이브 키가 발급되기 전까지는 의존하고 계신 동작을 바꾸는 변경이 위와 같이 라벨과 함께 배포될 수 있습니다. 라이브 전환 시점에 /v1은 고정되며, 그 이후 그러한 변경은 날짜가 붙은 버전으로만 배포됩니다. 그 버전으로 옮기실지는 귀사의 선택이며, 아무것도 하지 않으신 연동은 처음 작성하실 때의 동작을 그대로 유지합니다.
- Never held back by a version버전과 무관하게 적용되는 것
- A fix reaches you when the behavior it corrects was never documented. Security fixes, and corrections to amounts, reach you immediately and without exception.문서에 없던 동작을 바로잡는 수정은 버전과 상관없이 적용됩니다. 보안 수정과 금액을 바로잡는 수정은 예외 없이 즉시 적용됩니다.
- Keep a regression test회귀 테스트를 갖추십시오
- Assert on the fields your code reads, across a full lifecycle on your test key: create a payment, complete it, take the webhook, read the result back. Run it before go-live, and again after any entry labeled Breaking or Stricter. The Testing page lists the values that drive each scenario.코드가 읽는 필드를 테스트 키로 전체 흐름에 걸쳐 검증하십시오. 결제를 생성하고, 완료하고, 웹훅을 받고, 결과를 다시 조회하는 흐름입니다. 라이브 전환 전에 한 번, 그리고 Breaking이나 Stricter 라벨이 붙은 항목이 나올 때마다 다시 실행하십시오. 각 시나리오를 일으키는 값은 테스트 페이지에 정리되어 있습니다.
Conventions규약
Objects & fields객체와 필드
Metadata메타데이터
Payments, refunds and payment links accept metadata: your own key/value pairs, for tying our objects back to your records.결제, 환불, 결제 링크는 metadata를 받습니다. 직접 정의하신 키/값 쌍으로, OutlinePay 객체를 귀사의 기록과 연결하는 데 사용하십시오.
- Opaque to us내용을 해석하지 않음
- We never interpret the contents. They are stored, returned on every read, carried on every event that object emits, and forwarded to the processor.OutlinePay는 내용을 전혀 해석하지 않습니다. 저장되고, 모든 조회 시 반환되며, 해당 객체가 발행하는 모든 이벤트에 실려 전달되고, 결제 처리사에도 전달됩니다.
- Set once생성 시 한 번만 설정
- Set at creation. Metadata cannot be edited afterwards.생성 시 설정합니다. 메타데이터는 이후에 수정할 수 없습니다.
- Limits제한
- At most 50 pairs, keys up to 40 characters, values up to 500, stored as strings. Nested objects and arrays are rejected.최대 50쌍이며, 키는 40자, 값은 500자까지이고 문자열로 저장됩니다. 중첩된 객체와 배열은 거부됩니다.
- Reserved keys예약된 키
- Keys beginning outlinepay_, plus outline_fee and partner_fee, are ours and are rejected.outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 사용하며, 요청이 거부됩니다.
- Never secrets비밀 정보 금지
- It reaches the processor and is visible in their dashboard.메타데이터는 결제 처리사까지 전달되며 처리사의 대시보드에서 그대로 보입니다.
Forward-only fields전달 전용 필드
Fields marked forward-only are passed to the payment processor to prefill onboarding, then discarded.전달 전용(forward-only)으로 표시된 필드는 온보딩을 미리 채우기 위해 결제 처리사로 전달된 뒤 폐기됩니다.
- Which fields해당 필드
- tax_id, and every field under representative, supplied when you attach a processor.tax_id 및 representative 하위의 모든 필드이며, 결제 처리사를 연결하실 때 전달합니다.
- Never stored저장하지 않음
- They are never stored or returned, so they cannot appear in a later GET, an event payload, or a backup.이 값들은 저장되지도 반환되지도 않으므로, 이후의 GET 응답이나 이벤트 페이로드, 백업에 나타날 수 없습니다.
- Everything else그 외 전부
- Everything in a merchant's business is stored and comes back on the merchant.가맹점의 business에 포함된 모든 값은 저장되며 가맹점 객체로 반환됩니다.
Merchant-owned fields가맹점 소유 필드
Fields marked merchant-owned belong to the merchant once a processor is attached: the processor gives them ownership, so only they can change the value.가맹점 소유(merchant-owned)로 표시된 필드는 결제 처리사가 연결되는 순간 가맹점의 것이 됩니다. 결제 처리사가 소유권을 넘기므로 가맹점만 값을 변경할 수 있습니다.
- Which fields해당 필드
- product_description, industry_code, statement_descriptor and phone.product_description, industry_code, statement_descriptor, phone입니다.
- How they change변경되는 방식
- The merchant edits them in the processor's account-management component. We write the new value back onto the merchant and emit merchant.updated.가맹점이 결제 처리사의 계정 관리 컴포넌트에서 수정합니다. OutlinePay는 변경된 값을 가맹점 객체에 다시 반영하고 merchant.updated 이벤트를 발행합니다.
- Via the APIAPI를 통한 변경
- Create a merchant and Update a merchant accept them until a processor is attached. After that, Update a merchant rejects them.결제 처리사를 연결하기 전까지는 가맹점 생성과 가맹점 수정 모두에서 받습니다. 연결 이후에는 가맹점 수정에서 거부됩니다.
Processor-agnostic values프로세서 독립 값
Some enums, business.structure and the account-session components, use OutlinePay's own vocabulary rather than any one processor's. We translate each value to your processor's equivalent when we forward it, and store and return the OutlinePay value, so the same words work no matter which processor is behind the account.일부 enum과 business.structure, 그리고 계정 세션 컴포넌트는 특정 결제 처리사의 용어가 아니라 OutlinePay 자체 용어를 사용합니다. 전달 시 각 값을 해당 결제 처리사의 대응 값으로 변환하며, 저장하고 반환할 때는 OutlinePay 값을 사용합니다. 따라서 계정 뒤에 어떤 처리사가 있든 동일한 용어가 그대로 동작합니다.
Fields beginning processor_ are the exception: they carry the processor's own value, outside this contract. Read them, don't branch on them.processor_로 시작하는 필드는 예외입니다. 저희 값이 아니라 처리사의 값을 담으며 이 계약의 범위 밖에 있습니다. 읽으시되, 분기 조건으로는 쓰지 마십시오.
Write-time validation저장 시점 검증
A value the payment processor is known to refuse is refused when you send it, as 400 invalid_request with one details entry per refused field, so it cannot be stored at creation and then fail when the processor is attached.결제 처리사가 거부하는 것으로 확인된 값은 전송 시점에 곧바로 거부됩니다. 거부된 필드마다 details 항목을 하나씩 담은 400 invalid_request로 응답하므로, 생성 시에는 저장되었다가 처리사 연결 시점에 실패하는 일이 없습니다.
- URLsURL
- business.url must be a full http(s) address with a domain name, e.g. https://acme-trading.com. An IP address, a non-standard port, or a unicode domain (send its punycode xn-- form) is refused.business.url은 도메인 이름을 포함한 완전한 http(s) 주소여야 합니다. 예: https://acme-trading.com. IP 주소, 비표준 포트, 유니코드 도메인(퓨니코드 xn-- 형식으로 보내 주십시오)은 거부됩니다.
- Emails이메일
- The merchant's email, representative.email and a payment's customer.email need a name, an @, and a dotted domain, in ASCII.가맹점 email, representative.email, 결제의 customer.email에는 ASCII로 된 이름, @, 점이 포함된 도메인이 필요합니다.
- Addresses주소
- An address sent with any field needs its country, and a business address must be in the merchant's own country. For a US address, postal_code is 5 digits or ZIP+4, and state is the two-letter USPS code. US insular areas (GU, VI, AS, MP) aren't served by the processor. A representative's home address may be in any country.어떤 필드든 주소를 보내실 때는 country가 필요하며, 사업장 주소는 가맹점 자신의 국가에 있어야 합니다. 미국 주소의 postal_code는 5자리 또는 ZIP+4, state는 두 글자 USPS 코드입니다. 미국 도서 지역(GU, VI, AS, MP)은 결제 처리사가 지원하지 않습니다. 대표자의 자택 주소는 어느 국가든 가능합니다.
- Phones전화번호
- business.phone and representative.phone must parse as a phone number. E.164 always works, and national formats the processor can parse also pass.business.phone과 representative.phone은 전화번호로 해석 가능해야 합니다. E.164가 안전한 형식이며, 처리사가 해석할 수 있는 국가별 형식도 통과합니다.
- Category and descriptor업종 코드와 명세서 표기
- business.industry_code must be one of the ISO 18245 merchant category codes we support. business.statement_descriptor is 5 to 22 characters, contains a Latin letter, and has no angle brackets.business.industry_code는 저희가 지원하는 ISO 18245 업종 코드(MCC) 중 하나여야 합니다. business.statement_descriptor는 5~22자이고, 라틴 문자를 하나 이상 포함하며, 꺾쇠괄호는 쓸 수 없습니다.
- Identity신원 정보
- tax_id is the 9-digit US EIN, hyphens welcome. representative.date_of_birth is a past ISO date, at least 13 years back.tax_id는 9자리 미국 EIN이며 하이픈은 있어도 됩니다. representative.date_of_birth는 과거의 ISO 날짜로, 최소 13년 전이어야 합니다.
- What can still fail at attach처리사 연결 시에도 실패할 수 있는 것
- Checks only the processor can make, chiefly its own list of placeholder and shared website domains (example.com and the like). Those answer 400 with the field in the entry's param and the processor's sentence in its processor_message.처리사만 확인할 수 있는 검사, 주로 자리표시용·공용 웹사이트 도메인(example.com 등)에 대한 처리사 자체 목록입니다. 이 경우 항목의 param에 필드 이름을, processor_message에 처리사의 설명을 담은 400으로 응답합니다.
Conventions규약
Money movement자금 흐름
Onboarding is required before charging결제 전 온보딩 필수
Creating a merchant and attaching a processor does not make it chargeable. The processor still has to verify the merchant, and until it does, Create a payment and Create a payment link both refuse with 409 merchant_not_onboarded.가맹점을 생성하고 결제 처리사를 연결하는 것만으로는 결제를 받을 수 없습니다. 결제 처리사가 가맹점을 검증해야 하며, 검증 전까지 결제 생성과 결제 링크 생성은 모두 409 merchant_not_onboarded로 거부됩니다.
- How to clear it해결 방법
- Call Create an account session for the merchant and render the returned client_secret with the onboarding component. Onboarding happens only in that component, on your own page. There is no link to email.해당 가맹점으로 계정 세션 생성을 호출하고, 반환된 client_secret을 온보딩 컴포넌트로 렌더링하십시오. 온보딩은 귀사의 페이지에 삽입된 이 컴포넌트에서만 진행됩니다. 이메일로 보낼 수 있는 링크는 없습니다.
- How to know it worked완료 확인 방법
- The merchant's status turns active and its processors[].verified turns true. merchant.updated fires at that moment.가맹점의 status가 active로 바뀌고 processors[].verified가 true가 됩니다. 이 시점에 merchant.updated 이벤트가 발송됩니다.
- While you wait심사 대기 중
- After the merchant submits, the processor reviews. The same 409 is returned with a message saying so, and there is nothing to retry until the status changes. processors[].requirements tells that apart from a merchant that still owes something: awaiting names whose move it is, and outstanding names what is left.가맹점이 제출을 마치면 결제 처리사가 심사합니다. 이 경우에도 동일한 409가 반환되며 메시지로 대기 상태임을 알려드립니다. 상태가 바뀌기 전까지 재시도하실 것은 없습니다. 아직 제출할 항목이 남은 가맹점과는 processors[].requirements로 구분하실 수 있습니다. awaiting이 다음 차례가 누구인지, outstanding이 무엇이 남았는지 알려줍니다.
- The merchant terms가맹점 약관
- The onboarding component also shows the OutlinePay merchant terms ahead of the processor's form. The merchant accepts once, for every processor. A merchant verified without ever seeing them (an integration that bypasses outlinepay.js) is refused with 409 merchant_terms_not_accepted, and the fix is the same onboarding component.온보딩 컴포넌트는 결제 처리사의 양식에 앞서 OutlinePay 가맹점 약관도 표시합니다. 가맹점은 한 번만 동의하면 모든 결제 처리사에 적용됩니다. 약관을 본 적 없이 검증된 가맹점(outlinepay.js를 거치지 않은 연동)은 409 merchant_terms_not_accepted로 거부되며, 해결 방법은 동일하게 온보딩 컴포넌트입니다.
Payment methods결제 수단
payment_methods is an allow-list of categories in OutlinePay's vocabulary, translated to the processor's methods at the boundary. Provide an array to offer exactly those. Omit it and you get ["card", "wallet"].payment_methods는 OutlinePay 용어로 정의된 결제 수단 분류의 허용 목록이며, 경계에서 처리사의 수단으로 변환됩니다. 배열을 지정하시면 그 분류만 노출됩니다. 생략하시면 ["card", "wallet"]이 적용됩니다.
Categories combine freely. Offer a capped bank rail beside cards and we ask the customer which they'll use before pricing, and fees stay null until they answer.분류는 자유롭게 조합하실 수 있습니다. 상한이 적용되는 은행 수단을 카드와 함께 제공하시면, 수수료를 확정하기 전에 저희가 고객께 사용하실 수단을 여쭙습니다. 답변 전까지 수수료는 null입니다.
- Choosing bank_debitbank_debit 선택 기준
- Offer it when you can wait a few business days to know you've been paid, and for amounts above $7,500 where it's the only bank option. Offering it turns off the instant bank option your processor would otherwise present on a card checkout, which settles like a card and is better if you fulfill on payment.결제 확인까지 영업일 기준 며칠을 기다리실 수 있을 때, 그리고 은행 결제가 유일한 수단인 7,500달러 초과 금액에 적합합니다. 이 수단을 제공하시면 카드 체크아웃에서 처리사가 대신 노출하던 즉시 은행 결제 옵션이 비활성화됩니다. 그 옵션은 카드와 동일하게 정산되므로 결제 즉시 상품을 발송하시는 경우에는 오히려 유리합니다.
- bank_verificationbank_verification
- How the customer proves the account is theirs. instant_or_delayed (the default) also lets them confirm two small deposits instead, which accepts the most customers but can leave a payment processing for a fortnight. instant answers immediately, and customers whose bank cannot be linked that way cannot pay by bank at all.고객이 해당 계좌가 본인 것임을 증명하는 방식입니다. 기본값인 instant_or_delayed는 소액 입금 2건을 확인하는 방식도 허용하므로 가장 많은 고객을 수용하지만, 결제가 2주가량 processing 상태에 머무를 수 있습니다. instant는 결과를 즉시 알려주지만, 계좌 연동이 불가능한 고객은 은행 결제를 아예 이용할 수 없습니다.
| Category카테고리 | Covers (on Stripe)포함 수단 (Stripe) | How it works작동 방식 |
|---|---|---|
card |
Cards, Apple Pay, Google Pay, Link카드, Apple Pay, Google Pay, Link | Debit and credit cards. The card-based wallets (Apple Pay, Google Pay, Link) ride along automatically and can't be offered without cards.체크카드와 신용카드입니다. Apple Pay, Google Pay, Link처럼 카드 기반인 간편결제는 자동으로 함께 제공되며, 카드 없이는 단독으로 제공할 수 없습니다. |
wallet |
Cash App, Amazon PayCash App, Amazon Pay | Standalone wallets the customer pays from directly. (Apple Pay, Google Pay and Link are card-based, so they're part of card, not here.)고객이 직접 결제하는 독립형 간편결제입니다. (Apple Pay, Google Pay, Link는 카드 기반이므로 이곳이 아니라 card에 포함됩니다.) |
bnpl |
Klarna, Affirm, AfterpayKlarna, Affirm, Afterpay | Buy now, pay later. The customer splits the cost over time. You're paid in full up front.후불 결제입니다. 고객은 대금을 나누어 부담하고, 가맹점은 처음에 전액을 수령합니다. |
bank_debit |
ACH Direct DebitACH 계좌 직불 | Pull debit: the customer authorizes a pull from their US bank account. Settlement is delayed a few business days, so the payment sits in processing first, and it can fail after the customer has finished. Both our fee and yours are capped on it.출금 방식입니다. 고객이 미국 은행 계좌에서의 출금을 승인합니다. 정산이 영업일 기준 며칠 뒤에 이루어지므로 결제는 먼저 processing 상태에 머무르며, 고객이 결제를 마친 뒤에도 실패할 수 있습니다. OutlinePay 수수료와 파트너 수수료 모두 상한이 적용됩니다. |
bank_transfer |
Bank transfer, virtual account (가상계좌)계좌이체 · 가상계좌 | Push transfer: the customer is shown a virtual account number and sends the funds from their own bank. The payment sits in processing until the money arrives, and the same buyer keeps the same account number across payments. Requires customer.email when offered, and can't be offered on a payment link. Both our fee and yours are capped on it. US merchants only for now.입금 방식입니다. 고객에게 가상계좌 번호가 표시되고, 고객이 자신의 은행에서 자금을 보냅니다. 입금이 확인될 때까지 결제는 processing 상태에 머무르며, 같은 구매자는 결제할 때마다 같은 계좌번호를 사용합니다. 제공하려면 customer.email이 필요하고, 결제 링크에서는 제공할 수 없습니다. OutlinePay 수수료와 파트너 수수료 모두 상한이 적용됩니다. 현재는 미국 가맹점만 이용할 수 있습니다. |
Fees arrive just after the outcome수수료는 결과 직후에 도착합니다
Three fields can only be read off the charge itself, so they are still null the moment a payment succeeds or fails: fees.processor, the processor's own cut, processor_payment_method, what actually settled, and card, the card that settled it.세 필드는 결제 건 자체에서만 확인할 수 있으므로, 결제가 성공 또는 실패한 시점에는 아직 null입니다. 처리사가 취한 금액인 fees.processor, 실제로 정산된 수단인 processor_payment_method, 그리고 결제에 사용된 카드 정보인 card입니다.
- payment.updatedpayment.updated
- Fires a second or two after the outcome, carrying the same payment with the fields filled in. The status does not change, so read it as an amendment to the event before it. Usually one event covers every field. If the fee lags, the rest arrive first and a second event follows with the fee.결과 발생 후 1~2초 뒤에 발송되며, 해당 필드가 채워진 동일한 결제 객체를 담고 있습니다. status는 바뀌지 않으므로 직전 이벤트에 대한 정정으로 읽으시면 됩니다. 보통 한 번의 이벤트로 모든 필드가 전달되지만, 수수료 확인이 늦어지면 나머지가 먼저 도착하고 수수료를 담은 두 번째 이벤트가 뒤따릅니다.
- Until it arrives도착 전까지
- fees.total and merchant_net count an unread processor fee as zero, so both read high for those first seconds. On a $4,000 card that is $116.30 too much. Record net from payment.updated, not from payment.succeeded.fees.total과 merchant_net은 아직 확인되지 않은 처리사 수수료를 0으로 계산하므로, 처음 몇 초 동안 두 값이 실제보다 높게 표시됩니다. 4,000달러 카드 결제라면 116.30달러가 과다 계상됩니다. 정산 금액은 payment.succeeded가 아니라 payment.updated를 기준으로 기록하십시오.
- On a failure실패한 경우
- A returned bank debit still costs the merchant a flat return charge, so fees.processor is filled in there too. Our fee and yours read zero because the processor hands them back, and merchant_net is negative by exactly the return charge.반환된 은행 출금에도 반환 건당 정액 수수료가 발생하므로 실패한 결제에도 fees.processor가 채워집니다. OutlinePay 수수료와 파트너 수수료는 처리사가 반환하므로 0으로 표시되며, merchant_net은 정확히 그 반환 수수료만큼 음수가 됩니다.
- If it never comes도착하지 않는 경우
- A fee we cannot read is left null rather than guessed at zero, and a later reconciliation fills it in and emits then. Nothing else about the payment waits on it.확인할 수 없는 수수료는 0으로 추정하지 않고 null로 남겨 두며, 이후 대조 작업에서 값을 채우고 그 시점에 이벤트를 발송합니다. 결제의 다른 어떤 처리도 이 값을 기다리지 않습니다.
A dispute does not un-settle a payment분쟁은 결제 상태를 되돌리지 않습니다
A disputed payment keeps the status succeeded. Whether the money stayed is answered by the dispute, not the status.분쟁이 발생한 결제도 status는 succeeded로 유지됩니다. 대금이 남아 있는지는 status가 아니라 분쟁 객체가 알려줍니다.
- What it takes back회수되는 금액
- disputes[].amount_withheld is how much of the payment the processor is holding, counted from the moment the dispute opens rather than when it closes. disputes[].fee is what it charged to handle the dispute, a flat $15 on Stripe. fees.total and merchant_net both account for the pair, which is why merchant_net goes negative on a payment that was lost.disputes[].amount_withheld는 처리사가 보류 중인 금액이며, 분쟁이 종료된 시점이 아니라 개시된 시점부터 계산됩니다. disputes[].fee는 분쟁 처리 대가로 청구된 금액이며 Stripe에서는 정액 15달러입니다. fees.total과 merchant_net은 두 값을 모두 반영하므로, 패소한 결제의 merchant_net은 음수가 됩니다.
- Winning is not free승소해도 비용은 남습니다
- The amount comes back and the fee does not: amount_withheld returns to 0 and fee stays.금액은 반환되지만 수수료는 반환되지 않습니다. amount_withheld는 0으로 돌아가고 fee는 그대로 유지됩니다.
- No refund while it is held보류 중에는 환불 불가
- amount_refundable reads 0 whenever amount_withheld is above zero. The processor refuses a refund on a charged-back payment whether the dispute is still open or already lost. Winning makes the payment refundable again.amount_withheld가 0보다 크면 amount_refundable은 0으로 표시됩니다. 분쟁이 진행 중이든 이미 패소했든, 처리사는 회수된 결제에 대한 환불을 거부합니다. 승소하면 해당 결제는 다시 환불 가능해집니다.
- Fees are still charged수수료는 그대로 청구됩니다
- Our fee and yours are both kept, as on a refund. Your earnings on the payment are unchanged.OutlinePay 수수료와 파트너 수수료는 환불의 경우와 동일하게 모두 유지됩니다. 해당 결제에서 발생한 파트너 수익은 변하지 않습니다.
Conventions규약
Events & webhooks이벤트와 웹훅
Webhook delivery웹훅 전달
Events are POSTed to every active webhook endpoint, signed with the OutlinePay-Signature header. Each event carries the object as it stood at that moment. Delivery is at-least-once with no promised order.이벤트는 활성 상태인 모든 웹훅 엔드포인트로 POST 전달되며, OutlinePay-Signature 헤더로 서명됩니다. 각 이벤트는 그 시점의 객체 전체를 담고 있습니다. 전달은 최소 1회(at-least-once) 보장이고 순서는 보장되지 않습니다.
- What counts as delivered전달 완료의 기준
- Any 2xx response within 10 seconds. Return it before doing slow work: a handler that processes first and answers second gets retried for running long, and then processes the same event twice.10초 이내의 2xx 응답입니다. 느린 작업은 응답을 반환하신 뒤에 처리해 주십시오. 처리를 먼저 하고 응답을 나중에 하는 핸들러는 시간 초과로 재시도 대상이 되어 같은 이벤트를 두 번 처리하게 됩니다.
- Retries재시도
- A failed delivery is retried up to 8 times over roughly 90 minutes, with growing gaps. After the last attempt we stop delivering that event to that endpoint.실패한 전달은 간격을 늘려 가며 약 90분에 걸쳐 최대 8회 재시도합니다. 마지막 시도 이후에는 해당 이벤트를 그 엔드포인트로 더 이상 전달하지 않습니다.
- Duplicates중복 전달
- Retries mean the same event can arrive twice. Record the event ids you have handled and skip repeats.재시도 때문에 같은 이벤트가 두 번 도착할 수 있습니다. 처리하신 이벤트 id를 기록해 두시고, 중복은 건너뛰어 주십시오.
- No delivery order전달 순서 없음
- Two events about the same object can arrive out of order: a refund event, then its payment.succeeded. Every event is self-sufficient, so handle each on its own facts. Do not return an error to force redelivery in order, that only spends the retries. If you need the object's latest state, use its Retrieve endpoint.같은 객체에 대한 두 이벤트가 순서가 뒤바뀌어 도착할 수 있습니다. 환불 이벤트가 먼저 오고, 해당 payment.succeeded가 나중에 올 수도 있습니다. 모든 이벤트는 그 자체로 완결적이므로 각 이벤트는 담긴 사실만으로 처리해 주십시오. 순서를 맞춰 다시 받으려고 오류를 반환하지 마십시오. 재시도만 소모됩니다. 객체의 최신 상태가 필요하시면 해당 객체의 조회 엔드포인트를 사용해 주십시오.
- Missed events놓친 이벤트
- Nothing is redelivered after the retries run out. List events is the catch-up path: every event stays readable there, newest first in emission order, so fetch what you missed and process it as though it had been delivered.재시도가 모두 소진된 뒤에는 자동으로 다시 전달되지 않습니다. 이벤트 목록 조회가 보완 경로입니다. 모든 이벤트는 그곳에서 발행 순서 기준 최신순으로 계속 조회하실 수 있으므로, 놓치신 이벤트를 가져와 전달받은 것처럼 처리해 주십시오.
- Checking an event you received수신한 이벤트 확인
- Any event can be fetched again by its id: Retrieve an event returns the same envelope.수신하신 이벤트는 id로 언제든 다시 조회하실 수 있습니다. 이벤트 조회가 같은 봉투를 반환합니다.
- Replay protection재생 공격 방지
- The signature's timestamp bounds how long a captured delivery stays valid. Reject a timestamp older than a few minutes, as the verification sample in the Quickstart does. It marks when the delivery attempt was sent, not when the event was created, so late retries still verify.서명의 타임스탬프는 탈취된 전달 건이 유효한 시간을 제한합니다. 시작하기 가이드의 검증 예시처럼 몇 분 이상 지난 타임스탬프는 거부해 주십시오. 타임스탬프는 이벤트 생성 시각이 아니라 해당 전달 시도의 발송 시각이므로, 늦은 재시도도 정상적으로 검증됩니다.
Object객체
The Merchant objectMerchant 객체
The businesses you accept payments for. A merchant becomes chargeable in three steps, in this order: create it, attach a processor to open its account, then have the merchant finish onboarding in an embedded component on your page. Charges are refused until the third step lands.귀사가 대신 결제를 받는 사업자입니다. 가맹점은 세 단계를 순서대로 거쳐야 결제를 받을 수 있습니다. 가맹점을 생성하고, 결제 처리사를 연결해 계정을 개설한 뒤, 귀사의 페이지에 삽입된 임베드 컴포넌트에서 가맹점이 온보딩을 완료해야 합니다. 세 번째 단계가 끝나기 전까지 결제는 거부됩니다.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "merchant".고정 문자열 "merchant"입니다. |
name
|
string |
|
email
|
string |
|
status
|
enum |
Where the merchant stands with its processors: the field to read for whether it can charge today.가맹점이 결제 처리사와의 관계에서 어느 단계에 있는지, 즉 오늘 결제를 받을 수 있는지를 확인하는 필드입니다. `created`: no processor has verified the merchant yet. This one value covers both a merchant that has not started onboarding and one whose submission is still under review. To tell those apart, read processors[].onboarding_completed.`created`: 아직 어떤 결제 처리사도 가맹점을 검증하지 않았습니다. 온보딩을 시작하지 않은 가맹점과 제출 후 심사 중인 가맹점을 모두 포함하는 값이므로, 둘을 구분하시려면 processors[].onboarding_completed를 읽어 주십시오. `active`: a processor has verified the merchant and it can accept payments.`active`: 결제 처리사가 가맹점을 검증했으며 결제를 받을 수 있습니다. `restricted`: a processor verified the merchant earlier but has since limited the account, usually because it now wants more information. Only the merchant can clear it, by answering the processor in the embedded components. A merchant that was never verified stays `created`, and processors[].verified never returns to false, so `restricted` is the only signal that a merchant which used to be chargeable no longer is.`restricted`: 결제 처리사가 과거에 가맹점을 검증했지만 이후 계정을 제한한 상태이며, 대개 추가 정보를 요구하는 경우입니다. 임베드 컴포넌트에서 처리사의 요청에 답하는 방식으로 가맹점만 해제할 수 있습니다. 한 번도 검증되지 않은 가맹점은 `created`로 유지되고 processors[].verified는 false로 되돌아가지 않으므로, 결제를 받을 수 있었던 가맹점이 더 이상 받을 수 없게 되었다는 신호는 `restricted`뿐입니다. The API does not carry the reason for a restriction. The processor delivers it to the merchant in the `notifications` component, which is also the only place the merchant can answer it. So when you see `restricted`, put the merchant in front of `notifications` and `account_management` (see Create an account session); we emit merchant.updated when the status returns to active.제한 사유는 API로 전달되지 않습니다. 결제 처리사가 `notifications` 컴포넌트를 통해 가맹점에 직접 전달하며, 가맹점이 답할 수 있는 곳도 그곳뿐입니다. 따라서 `restricted`가 보이면 가맹점에게 `notifications`와 `account_management` 컴포넌트를 보여 주십시오(계정 세션 생성 참고). 상태가 active로 돌아오면 merchant.updated 이벤트를 발송합니다.
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
country
|
string |
The merchant's legal-entity country, ISO 3166-1 alpha-2. Where the business is registered, not where its customers are. US today; other countries are on our roadmap.가맹점 법인의 국가이며 ISO 3166-1 alpha-2 코드입니다. 고객이 있는 곳이 아니라 사업자가 등록된 곳입니다. 현재는 US만 지원하며, 다른 국가는 로드맵에 있습니다. |
locale
|
string |
The language this merchant's onboarding renders in, or null if none was given (which onboards in English).이 가맹점의 온보딩이 렌더링되는 언어입니다. 지정하지 않으셨다면 null이며, 영어로 온보딩됩니다. nullable |
entity_type
|
enum |
The legal entity type, if any.법적 실체 유형입니다(있는 경우). nullable
One of다음 중 하나
|
default_processor
|
string |
The rail a charge uses when the request names none. Null until the first processor is attached, which becomes the default; it never changes on its own after that.요청에 결제 처리사를 지정하지 않았을 때 결제가 사용하는 경로입니다. 첫 처리사를 연결하기 전까지는 null이며, 연결된 처리사가 기본값이 됩니다. 이후 저절로 바뀌지 않습니다. nullable |
business
|
object |
Commercial details about the merchant's business. Fields marked merchant-owned are the merchant's to edit once they have onboarded, so they only ever travel inward.가맹점 사업체에 대한 상업 정보입니다. merchant-owned로 표시된 필드는 온보딩을 마친 가맹점만 수정할 수 있으므로 안쪽 방향으로만 이동합니다. Seeded by what you supply at creation, which is why it can change without a call from you: the merchant edits its details at the processor and the sync above brings them back here. Only business-level data is kept. Representative details are forwarded to the processor and never stored, so they are never returned here.생성 시 제공하신 값으로 시작하며, 그래서 귀사의 호출 없이도 바뀔 수 있습니다. 가맹점이 처리사에서 정보를 수정하면 위의 동기화가 이곳으로 가져옵니다. 사업체 수준의 데이터만 보관합니다. 대표자 정보는 처리사로 전달만 하고 저장하지 않으므로 이곳에 반환되지 않습니다. nullable |
business.legal_name
|
string |
Registered legal name, if it differs from `name`.등록된 법적 상호입니다. `name`과 다른 경우에 보내 주십시오. |
business.structure
|
enum |
The merchant's legal structure, in OutlinePay's processor-agnostic vocabulary; we translate it to your processor's own value. Applies to a company; an individual has none. These map to, in order: sole_proprietorship, single_member_llc, multi_member_llc, private_corporation, private_partnership.OutlinePay의 처리사 독립 용어로 표현한 가맹점의 법적 형태이며, 처리사의 값으로 변환해 전달합니다. 법인에만 적용되고 개인에게는 없습니다. 순서대로 sole_proprietorship, single_member_llc, multi_member_llc, private_corporation, private_partnership에 대응합니다.
One of다음 중 하나
|
business.phone
merchant-owned |
string |
Business phone. Use E.164: '+', the country code, then the subscriber number, e.g. +12125550123 (US) or +821012345678 (KR). A phone no processor could parse is refused as a 400 invalid_request naming this field.사업자 전화번호입니다. E.164 형식('+', 국가 코드, 가입자 번호 순)을 사용해 주십시오. 예: +12125550123(미국), +821012345678(한국). 어떤 처리사도 해석할 수 없는 전화번호는 이 필드를 지목한 400 invalid_request로 거부됩니다. |
business.url
|
string |
Public website: a full http(s) URL with a domain name, e.g. https://hanui.example. The processor additionally refuses placeholder and shared domains (example.com and the like) when it is attached.공개 웹사이트입니다. 도메인 이름을 포함한 완전한 http(s) URL이어야 합니다. 예: https://hanui.example. 자리표시용·공용 도메인(example.com 등)은 처리사 연결 시점에 처리사가 추가로 거부합니다. |
business.product_description
merchant-owned |
string |
One or two sentences on what the merchant sells.가맹점이 판매하는 상품에 대한 한두 문장의 설명입니다. |
business.industry_code
merchant-owned |
string |
Four-digit merchant category code (MCC) classifying what the business sells: the card networks' ISO 18245 standard, not ours. Common examples: 5399 general merchandise, 5812 restaurants, 5691 clothing, 5734 software. Omit it and the processor infers one from the website and product description. We accept the codes listed at https://outlinepay.com/docs/mccs and refuse any other value naming this field.사업체가 판매하는 품목을 분류하는 4자리 업종 코드(MCC)로, OutlinePay가 아니라 카드 네트워크의 ISO 18245 표준입니다. 흔한 예: 5399 종합 소매, 5812 음식점, 5691 의류, 5734 소프트웨어. 생략하시면 처리사가 웹사이트와 상품 설명으로 추정합니다. 지원 코드 목록 (https://outlinepay.com/docs/mccs)의 코드를 받으며, 그 외의 값은 이 필드를 지목해 거부됩니다. |
business.statement_descriptor
merchant-owned |
string |
What buyers see on their card statement. 5 to 22 characters, at least one Latin letter, no angle brackets. Keep it recognisable, or it drives chargebacks.구매자의 카드 명세서에 표시되는 문구입니다. 5~22자이고, 라틴 문자를 하나 이상 포함하며, 꺾쇠괄호는 쓸 수 없습니다. 알아보기 쉽게 정하지 않으면 지불 거절의 원인이 됩니다. |
business.address
|
object |
|
business.address.line1
|
string |
|
business.address.line2
|
string |
|
business.address.city
|
string |
|
business.address.state
|
string |
Two-letter state or province code. For a US address, the USPS code. The processor cannot serve US insular areas (GU, VI, AS, MP).두 글자 주/도 코드입니다. 미국 주소는 USPS 코드를 사용하며, 미국 도서 지역(GU, VI, AS, MP)은 결제 처리사가 지원하지 않습니다. |
business.address.postal_code
|
string |
Postal code. For a US address, 5 digits or ZIP+4, e.g. 19104 or 19104-2617.우편번호입니다. 미국 주소는 5자리 또는 ZIP+4 형식입니다. 예: 19104, 19104-2617. |
business.address.country
|
string |
Two-letter ISO country code, required whenever an address is sent. This is the country of *this address*: a business address must be in the merchant's own country (the top-level `country` on the merchant), while a representative's home address may be anywhere.두 글자 ISO 국가 코드로, 주소를 보내실 때는 필수입니다. 이는 *이 주소*의 국가입니다. 사업장 주소는 가맹점 자신의 국가(가맹점의 최상위 `country`)에 있어야 하며, 대표자의 자택 주소는 어느 국가든 가능합니다. |
processors
|
array<object> |
|
processors[].processor
|
string |
|
processors[].account_id
|
string |
The processor's own account identifier (for Stripe, the connected account id, e.g. "acct_1AbC..."). Null in the brief window before the account is opened.결제 처리사 자체의 계정 식별자입니다(Stripe의 경우 연결 계정 id, 예: "acct_1AbC..."). 계정이 개설되기 전의 짧은 시간 동안은 null입니다. nullable |
processors[].onboarding_completed
|
boolean |
True once the merchant has submitted its details to the processor. It reports that the merchant did its part, not that the processor accepted them, so read it together with verified rather than instead of it. While either is false, requirements says what is still outstanding and whose move it is. It never returns to false once set.가맹점이 결제 처리사에 정보를 제출하면 true가 됩니다. 가맹점이 할 일을 마쳤다는 뜻이지 처리사가 승인했다는 뜻이 아니므로, verified 대신이 아니라 verified와 함께 읽어 주십시오. 둘 중 하나라도 false인 동안에는 requirements가 무엇이 남아 있고 다음 차례가 누구인지 알려줍니다. 한 번 true가 되면 false로 되돌아가지 않습니다. |
processors[].representative_prefilled
|
boolean |
True once the representative supplied at attach reached the processor. False when none was supplied, or when it was rejected, in which case Attach a processor accepts the corrected one. A delivery flag only: the representative itself is forward-only and never returned.처리사 연결 시 제공한 representative가 처리사에 전달되면 true가 됩니다. 제공하지 않았거나 거부된 경우 false이며, 거부된 경우 Attach a processor가 수정한 representative를 다시 받습니다. 전달 여부만 나타내는 플래그입니다. representative 자체는 전달 후 폐기되며 응답으로 반환되지 않습니다. |
processors[].requirements
|
object |
What the merchant still owes this processor, or null once it owes nothing. onboarding_completed and verified say a merchant is not through. This says what is left.가맹점이 이 결제 처리사에 아직 제출해야 하는 항목이며, 남은 것이 없으면 null입니다. onboarding_completed와 verified는 가맹점이 아직 통과하지 못했다는 사실을 알려주고, 이 필드는 무엇이 남았는지를 알려줍니다. nullable |
processors[].requirements.status
|
enum |
How urgent the strictest outstanding item is. `overdue` is holding the account back now, `due` keeps it working, `upcoming` is wanted once the merchant's volume passes the processor's thresholds.남은 항목 중 가장 급한 것의 시급도입니다. `overdue`는 지금 계정을 막고 있고, `due`는 계정을 계속 사용하려면 필요하며, `upcoming`은 가맹점의 거래액이 처리사의 기준을 넘으면 필요합니다.
One of다음 중 하나
|
processors[].requirements.blocks_charges
|
boolean |
True when the merchant cannot take a payment until something here is resolved. This is the one that decides whether to show a checkout.여기 있는 항목이 해결되기 전까지 가맹점이 결제를 받을 수 없으면 true입니다. 결제 화면을 보여줄지 판단할 때 이 값을 사용하십시오. |
processors[].requirements.blocks_payouts
|
boolean |
True when the merchant cannot be paid out until something here is resolved.여기 있는 항목이 해결되기 전까지 가맹점이 정산을 받을 수 없으면 true입니다. |
processors[].requirements.awaiting
|
enum |
Whose move is next. `merchant` means the account session and onboarding component will collect what is missing. `processor` means it has what it needs and is reviewing, so there is nothing to do but wait.다음 차례가 누구인지 나타냅니다. `merchant`는 계정 세션과 온보딩 컴포넌트로 부족한 항목을 수집하면 된다는 뜻입니다. `processor`는 처리사가 필요한 것을 모두 받아 심사 중이므로 기다리는 것 외에 할 일이 없다는 뜻입니다.
One of다음 중 하나
|
processors[].requirements.refreshed_at
|
string |
When we last read this from the processor.이 정보를 결제 처리사에서 마지막으로 읽어온 시각입니다. |
processors[].requirements.outstanding
|
array<object> |
One entry per thing the merchant has to do, the ones blocking charges first. Can be empty while the rest of this object is populated: the processor sometimes restricts an account before it says which fields it wants, and an empty list is not the same answer as a null requirements.가맹점이 해야 할 일마다 항목 하나씩이며, 결제를 막는 항목이 먼저 옵니다. 이 객체의 나머지 값이 채워진 상태에서도 비어 있을 수 있습니다. 결제 처리사가 필요한 필드를 알려주기 전에 계정을 먼저 제한하는 경우가 있기 때문이며, 빈 배열은 requirements가 null인 것과 다른 답입니다. |
processors[].requirements.outstanding[].code
|
enum |
What the merchant has to do, in OutlinePay's vocabulary: accept the processor's agreement, supply the representative's identity, add a payout account, or correct the business category or details. Branch on this. `other` means the processor asked for something we have no word for yet, and processor_items is then the only description of it.가맹점이 해야 할 일을 OutlinePay의 용어로 나타냅니다. 결제 처리사의 약관 동의, 대표자 신원 제출, 정산 계좌 등록, 업종이나 사업자 정보 수정 중 하나입니다. 분기 처리는 이 값으로 하십시오. `other`는 처리사가 요구한 항목에 대응하는 용어가 아직 없다는 뜻이며, 이 경우 processor_items가 그 항목을 설명하는 유일한 단서입니다.
One of다음 중 하나
|
processors[].requirements.outstanding[].blocks
|
array<string> |
What this item holds up. A group's value covers every item in it, so an item blocking charges and another blocking payouts give a group that lists both. For the exact answer read blocks_charges and blocks_payouts on the object above.이 항목이 막고 있는 것입니다. 그룹의 값은 그룹에 속한 모든 항목을 합친 것이므로, 결제를 막는 항목과 정산을 막는 항목이 같은 그룹에 있으면 둘 다 표시됩니다. 정확한 답이 필요하면 상위 객체의 blocks_charges와 blocks_payouts를 읽어 주십시오. |
processors[].requirements.outstanding[].processor_items
|
array<string> |
The processor's own names for the fields behind this item, verbatim. Useful for telling a merchant precisely what failed, and outside our compatibility contract like every processor_ field.이 항목에 해당하는 필드를 결제 처리사가 부르는 이름 그대로입니다. 가맹점에게 정확히 무엇이 부족한지 전달할 때 유용하며, 다른 모든 processor_ 필드와 마찬가지로 호환성 보장 대상이 아닙니다. |
processors[].verified
|
boolean |
True once the processor has accepted the merchant and will take charges for it. This is the one that gates money: until it is true, creating a payment or a payment link is refused with 409 merchant_not_onboarded, whatever onboarding_completed says. It turns true at the same moment the merchant's status becomes active, and a merchant.updated event is emitted then, so you can wait on the event instead of polling. It never returns to false, so it answers "has this merchant ever been accepted" rather than "can it charge right now"; for the second question read status, which is where a later restriction shows up.결제 처리사가 가맹점을 승인해 결제를 받아 주기 시작하면 true가 됩니다. 자금을 결정하는 값이 바로 이것입니다. true가 되기 전까지는 onboarding_completed와 무관하게 결제 생성과 결제 링크 생성이 409 merchant_not_onboarded로 거부됩니다. 가맹점의 status가 active가 되는 순간 함께 true가 되고 그때 merchant.updated 이벤트가 발송되므로, 폴링 대신 이벤트를 기다리셔도 됩니다. false로 되돌아가지 않으므로 "지금 결제 가능한가"가 아니라 "승인된 적이 있는가"에 답하는 값이며, 전자는 이후의 제한이 반영되는 status를 읽어 주십시오. |
terms_acceptance
|
object |
The merchant's acceptance of the OutlinePay merchant terms, or null if they have not accepted yet. You never write this: the merchant agrees on the terms screen the onboarding component shows ahead of the processor's form, we record it, and merchant.updated announces the change. One acceptance covers every processor. A merchant without one cannot take payments (409 merchant_terms_not_accepted), except merchants created before 2026-08-16, who are exempt until they next pass through onboarding.가맹점의 OutlinePay 가맹점 약관 동의 내역이며, 아직 동의하지 않았다면 null입니다. 이 필드는 직접 쓰실 수 없습니다. 가맹점이 온보딩 컴포넌트가 결제 처리사의 양식에 앞서 보여주는 약관 화면에서 동의하면 당사가 기록하고, merchant.updated 이벤트로 변경을 알려드립니다. 한 번의 동의가 모든 결제 처리사에 적용됩니다. 동의 내역이 없는 가맹점은 결제를 받을 수 없으며(409 merchant_terms_not_accepted), 2026-08-16 이전에 생성된 가맹점은 다음 온보딩을 거치기 전까지 예외입니다. nullable |
terms_acceptance.version
|
string |
The terms version accepted.동의한 약관 버전입니다. |
terms_acceptance.accepted_at
|
string |
|
created_at
|
string |
{
"id": "mrc_9f2c8bAaZ1kQ",
"object": "merchant",
"name": "Acme Trading Co.",
"email": "[email protected]",
"status": "active",
"mode": "test",
"entity_type": "company",
"business": {
"legal_name": "Acme Trading Co. LLC",
"structure": "llc",
"phone": "+12125550123",
"url": "https://acme.example",
"product_description": "Imported kitchenware and small appliances.",
"industry_code": "5722",
"statement_descriptor": "ACME TRADING",
"address": {
"line1": "1600 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19103",
"country": "US"
}
},
"processors": [
{
"processor": "stripe",
"account_id": "acct_1AbCdEfGhIjKlMnO",
"onboarding_completed": true,
"verified": true,
"representative_prefilled": true
}
],
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/merchants
Create a merchant가맹점 생성
Creates a merchant and returns it with an empty `processors` list. This does not open a payment-processor account: that is a separate step, Attach a processor, so a merchant can exist before and independently of any processor.가맹점을 생성하고 `processors`가 빈 목록인 상태로 반환합니다. 이 호출은 결제 처리사 계정을 개설하지 않습니다. 계정 개설은 결제 처리사 연결이라는 별도 단계이므로, 가맹점은 어떤 결제 처리사보다 먼저, 그리고 처리사와 무관하게 존재할 수 있습니다.
- Prefill사전 입력
- business is commercial detail you already hold. We store it and hand it to the processor later so onboarding stops asking the merchant for it. All of it is returned on the merchant.business는 귀사가 이미 보유하고 계신 사업 정보입니다. OutlinePay가 저장해 두었다가 이후 결제 처리사에 전달하므로 온보딩에서 가맹점에 다시 묻지 않습니다. 모든 값은 가맹점 객체로 반환됩니다.
- Not accepted here이곳에서 받지 않는 항목
- The forward-only tax_id and representative. You supply those when you attach a processor, because we never store them.전달 전용인 tax_id와 representative입니다. 이 값들은 저장하지 않으므로, 결제 처리사를 연결하실 때 전달하십시오.
- Accuracy정확성에 대한 책임
- Prefilling is not attesting. The merchant, not you, is the party who confirms to the processor that these details are true, and every value you send stays editable during onboarding. Tell them which ones came from you so they can check each one.사전 입력은 사실 확인이 아닙니다. 이 정보가 사실임을 결제 처리사에 확인하는 주체는 귀사가 아니라 가맹점이며, 귀사가 전달한 모든 값은 온보딩 중에 계속 수정할 수 있습니다. 가맹점이 각 항목을 확인할 수 있도록 어떤 값이 귀사가 제공한 것인지 알려 주십시오.
Conventions규약 Merchant-owned fields가맹점 소유 필드
Emits이벤트 발행
merchant.created
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
name
required |
string |
|
email
required |
string |
|
country
required |
string |
The merchant's legal-entity country, ISO 3166-1 alpha-2. Where the business is registered, not where its customers are. Required, and never inferred, because it decides the onboarding requirements. `US` is the only country we onboard today: a merchant created with any other country is accepted here and then refused when you attach a processor, since that is where the entity is actually opened. Other countries are on our roadmap; see https://outlinepay.com/docs/countries and talk to us about yours.가맹점 법인의 국가이며 ISO 3166-1 alpha-2 코드입니다. 고객이 있는 곳이 아니라 사업자가 등록된 곳입니다. 온보딩 요건을 결정하므로 필수이며 추정하지 않습니다. 현재 온보딩 가능한 국가는 `US`뿐입니다. 다른 국가로 생성된 가맹점은 이 호출에서는 수락되지만 결제 처리사를 연결할 때 거부됩니다. 실제 법인 계정 개설이 그 시점에 일어나기 때문입니다. 다른 국가는 로드맵에 있습니다. https://outlinepay.com/docs/countries 를 참고하시고 필요하신 국가를 알려 주십시오. |
locale
optional |
enum |
The language this merchant reads. It decides what language their onboarding form is rendered in and what language the payment processor writes to them in afterwards, so send it if you know it. Optional: leave it out and the merchant is onboarded in English. `en` and `ko` are what we support today. Anything else is rejected rather than quietly downgraded to English, so that a language we cannot serve yet fails where you can see it. Tell us which ones you need and we will add them.이 가맹점이 읽는 언어입니다. 온보딩 양식이 렌더링되는 언어와 이후 결제 처리사가 가맹점에 보내는 안내의 언어를 결정하므로, 알고 계시다면 보내 주십시오. 선택 사항이며, 생략하시면 영어로 온보딩됩니다. 현재 지원 언어는 `en`과 `ko`입니다. 그 외의 값은 조용히 영어로 대체하는 대신 거부하므로, 아직 지원하지 않는 언어는 보이는 곳에서 실패합니다. 필요하신 언어를 알려 주시면 추가하겠습니다.
One of다음 중 하나
|
entity_type
optional |
enum |
Whether the merchant is a registered business or a person trading under their own name.가맹점이 등록된 사업체인지, 본인 명의로 거래하는 개인인지입니다.
One of다음 중 하나
|
business
optional |
object |
Commercial details about the merchant's business. Fields marked merchant-owned are the merchant's to edit once they have onboarded, so they only ever travel inward.가맹점 사업체에 대한 상업 정보입니다. merchant-owned로 표시된 필드는 온보딩을 마친 가맹점만 수정할 수 있으므로 안쪽 방향으로만 이동합니다. The details you already hold. Stored and returned on the merchant in full. The forward-only `tax_id` and `representative` are not accepted here: you supply them when you attach a processor.이미 보유하고 계신 정보입니다. 저장되어 가맹점 객체로 온전히 반환됩니다. 전달 전용인 `tax_id`와 `representative`는 여기서 받지 않으며, 결제 처리사를 연결하실 때 전달합니다. |
business.legal_name
optional |
string |
Registered legal name, if it differs from `name`.등록된 법적 상호입니다. `name`과 다른 경우에 보내 주십시오. |
business.structure
optional |
enum |
The merchant's legal structure, in OutlinePay's processor-agnostic vocabulary; we translate it to your processor's own value. Applies to a company; an individual has none. These map to, in order: sole_proprietorship, single_member_llc, multi_member_llc, private_corporation, private_partnership.OutlinePay의 처리사 독립 용어로 표현한 가맹점의 법적 형태이며, 처리사의 값으로 변환해 전달합니다. 법인에만 적용되고 개인에게는 없습니다. 순서대로 sole_proprietorship, single_member_llc, multi_member_llc, private_corporation, private_partnership에 대응합니다.
One of다음 중 하나
|
business.phone
optional merchant-owned |
string |
Business phone. Use E.164: '+', the country code, then the subscriber number, e.g. +12125550123 (US) or +821012345678 (KR). A phone no processor could parse is refused as a 400 invalid_request naming this field.사업자 전화번호입니다. E.164 형식('+', 국가 코드, 가입자 번호 순)을 사용해 주십시오. 예: +12125550123(미국), +821012345678(한국). 어떤 처리사도 해석할 수 없는 전화번호는 이 필드를 지목한 400 invalid_request로 거부됩니다. |
business.url
optional |
string |
Public website: a full http(s) URL with a domain name, e.g. https://hanui.example. The processor additionally refuses placeholder and shared domains (example.com and the like) when it is attached.공개 웹사이트입니다. 도메인 이름을 포함한 완전한 http(s) URL이어야 합니다. 예: https://hanui.example. 자리표시용·공용 도메인(example.com 등)은 처리사 연결 시점에 처리사가 추가로 거부합니다. |
business.product_description
optional merchant-owned |
string |
One or two sentences on what the merchant sells.가맹점이 판매하는 상품에 대한 한두 문장의 설명입니다. |
business.industry_code
optional merchant-owned |
string |
Four-digit merchant category code (MCC) classifying what the business sells: the card networks' ISO 18245 standard, not ours. Common examples: 5399 general merchandise, 5812 restaurants, 5691 clothing, 5734 software. Omit it and the processor infers one from the website and product description. We accept the codes listed at https://outlinepay.com/docs/mccs and refuse any other value naming this field.사업체가 판매하는 품목을 분류하는 4자리 업종 코드(MCC)로, OutlinePay가 아니라 카드 네트워크의 ISO 18245 표준입니다. 흔한 예: 5399 종합 소매, 5812 음식점, 5691 의류, 5734 소프트웨어. 생략하시면 처리사가 웹사이트와 상품 설명으로 추정합니다. 지원 코드 목록 (https://outlinepay.com/docs/mccs)의 코드를 받으며, 그 외의 값은 이 필드를 지목해 거부됩니다. |
business.statement_descriptor
optional merchant-owned |
string |
What buyers see on their card statement. 5 to 22 characters, at least one Latin letter, no angle brackets. Keep it recognisable, or it drives chargebacks.구매자의 카드 명세서에 표시되는 문구입니다. 5~22자이고, 라틴 문자를 하나 이상 포함하며, 꺾쇠괄호는 쓸 수 없습니다. 알아보기 쉽게 정하지 않으면 지불 거절의 원인이 됩니다. |
business.address
optional |
object |
|
business.address.line1
optional |
string |
|
business.address.line2
optional |
string |
|
business.address.city
optional |
string |
|
business.address.state
optional |
string |
Two-letter state or province code. For a US address, the USPS code. The processor cannot serve US insular areas (GU, VI, AS, MP).두 글자 주/도 코드입니다. 미국 주소는 USPS 코드를 사용하며, 미국 도서 지역(GU, VI, AS, MP)은 결제 처리사가 지원하지 않습니다. |
business.address.postal_code
optional |
string |
Postal code. For a US address, 5 digits or ZIP+4, e.g. 19104 or 19104-2617.우편번호입니다. 미국 주소는 5자리 또는 ZIP+4 형식입니다. 예: 19104, 19104-2617. |
business.address.country
optional |
string |
Two-letter ISO country code, required whenever an address is sent. This is the country of *this address*: a business address must be in the merchant's own country (the top-level `country` on the merchant), while a representative's home address may be anywhere.두 글자 ISO 국가 코드로, 주소를 보내실 때는 필수입니다. 이는 *이 주소*의 국가입니다. 사업장 주소는 가맹점 자신의 국가(가맹점의 최상위 `country`)에 있어야 하며, 대표자의 자택 주소는 어느 국가든 가능합니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "name" => "Acme Trading Co.", "email" => "[email protected]", "country" => "US", "entity_type" => "company", "business" => [ "legal_name" => "Acme Trading Co. LLC", "structure" => "llc", "phone" => "+12125550123", "url" => "https://acme.example", "product_description" => "Imported kitchenware and small appliances.", "industry_code" => "5722", "statement_descriptor" => "ACME TRADING", "address" => [ "line1" => "1600 Market St", "city" => "Philadelphia", "state" => "PA", "postal_code" => "19103", "country" => "US", ], ], ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/merchants" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Trading Co.", "email": "[email protected]", "country": "US", "entity_type": "company", "business": { "legal_name": "Acme Trading Co. LLC", "structure": "llc", "phone": "+12125550123", "url": "https://acme.example", "product_description": "Imported kitchenware and small appliances.", "industry_code": "5722", "statement_descriptor": "ACME TRADING", "address": { "line1": "1600 Market St", "city": "Philadelphia", "state": "PA", "postal_code": "19103", "country": "US" } } }'
Response응답
Returns a Merchant.Merchant 객체를 반환합니다.
{
"id": "mrc_9f2c8bAaZ1kQ",
"object": "merchant",
"name": "Acme Trading Co.",
"email": "[email protected]",
"status": "created",
"mode": "test",
"entity_type": "company",
"business": {
"legal_name": "Acme Trading Co. LLC",
"structure": "llc",
"phone": "+12125550123",
"url": "https://acme.example",
"product_description": "Imported kitchenware and small appliances.",
"industry_code": "5722",
"statement_descriptor": "ACME TRADING",
"address": {
"line1": "1600 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19103",
"country": "US"
}
},
"processors": [],
"created_at": "2026-07-21T12:00:00Z"
}
GET /v1/merchants
List merchants가맹점 목록 조회
Your merchants, newest first.귀사의 가맹점을 최신순으로 반환합니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants?limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/merchants?limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of Merchant objects: { "data": [...], "has_more": bool }.Merchant 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/merchants/{id}
Retrieve a merchant가맹점 조회
The authoritative merchant record, including per-processor onboarding/verification state.결제 처리사별 온보딩 및 인증 상태를 포함한 가맹점의 기준 정보입니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The merchant id.가맹점 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a Merchant.Merchant 객체를 반환합니다.
{
"id": "mrc_9f2c8bAaZ1kQ",
"object": "merchant",
"name": "Acme Trading Co.",
"email": "[email protected]",
"status": "active",
"mode": "test",
"entity_type": "company",
"business": {
"legal_name": "Acme Trading Co. LLC",
"structure": "llc",
"phone": "+12125550123",
"url": "https://acme.example",
"product_description": "Imported kitchenware and small appliances.",
"industry_code": "5722",
"statement_descriptor": "ACME TRADING",
"address": {
"line1": "1600 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19103",
"country": "US"
}
},
"processors": [
{
"processor": "stripe",
"account_id": "acct_1AbCdEfGhIjKlMnO",
"onboarding_completed": true,
"verified": true,
"representative_prefilled": true
}
],
"created_at": "2026-07-21T12:00:00Z"
}
PATCH /v1/merchants/{id}
Update a merchant가맹점 수정
Updates the merchant's processor-agnostic business identity. Changes travel the other way too, with no call from you: when the merchant edits their details at the processor, we write them back here automatically.결제 처리사와 무관한 가맹점의 사업자 정보를 수정합니다. 반대 방향으로도 반영됩니다. 가맹점이 결제 처리사에서 정보를 수정하면 귀사의 별도 호출 없이 이곳에 자동으로 반영됩니다.
- Merge semantics병합 방식
- A field you omit is left unchanged, a field you send is set, and a field you send blank is cleared.생략하신 필드는 그대로 유지되고, 전달하신 필드는 해당 값으로 설정되며, 빈 값으로 전달하신 필드는 삭제됩니다.
- Merchant-owned가맹점 소유 항목
- product_description, industry_code, statement_descriptor and phone are editable here only until a processor is attached. From then on the merchant owns them: they are edited in the account-management component and reach us through the inbound sync instead.product_description, industry_code, statement_descriptor, phone은 결제 처리사를 연결하기 전까지만 이곳에서 수정할 수 있습니다. 연결 이후에는 가맹점이 소유하므로, 계정 관리 컴포넌트에서 수정되고 인바운드 동기화를 통해 OutlinePay로 전달됩니다.
- Not accepted here이곳에서 받지 않는 항목
- The forward-only tax_id and representative, which belong to the attach endpoint.전달 전용인 tax_id와 representative이며, 결제 처리사 연결 엔드포인트에 속합니다.
- Propagation전파 방식
- Stored here, then pushed to every attached processor account, matching fields best-effort: each processor receives the ones it models and anything it cannot model is still stored here, just not forwarded. Today legal_name, structure and address reach the processor only for a company, since an individual's identity is held as a person rather than a business.이곳에 저장한 뒤 연결된 모든 결제 처리사 계정에 최선 노력으로 전달합니다. 각 처리사는 자신이 다루는 항목만 수신하며, 처리사가 다루지 않는 항목도 이곳에는 저장되고 전달만 되지 않습니다. 현재 legal_name, structure, address는 법인인 경우에만 처리사로 전달됩니다. 개인 사업자의 신원은 사업체가 아니라 개인으로 관리되기 때문입니다.
Conventions규약 Merchant-owned fields가맹점 소유 필드
Emits이벤트 발행
merchant.updated
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The merchant id.가맹점 id입니다. |
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
entity_type
optional |
enum |
Set-only. Sending it blank does not clear it.설정 전용입니다. 빈 값을 보내도 삭제되지 않습니다.
One of다음 중 하나
|
locale
optional |
enum |
The language this merchant reads. Change it when you learn you had it wrong, or when the merchant asks: it was previously fixed at creation, and a merchant who signed up in the wrong language stayed in it.이 가맹점이 읽는 언어입니다. 잘못 알고 계셨음을 알게 되었거나 가맹점이 요청할 때 변경하십시오. 이전에는 생성 시 고정되어, 잘못된 언어로 가입한 가맹점이 그 언어에 계속 머물렀습니다. Follows this endpoint's merge rule. Omit it and the language is left alone; send `en` or `ko` to set it; send it blank to clear it, which returns the merchant to being onboarded in English.이 엔드포인트의 병합 규칙을 따릅니다. 생략하시면 그대로 두고, `en`이나 `ko`를 보내시면 설정되며, 빈 값을 보내시면 삭제되어 영어 온보딩으로 돌아갑니다. It takes effect on the next account session you create. Components already on screen keep the locale they were initialised with, so by default the merchant sees the change on their next page load. If you want it sooner, the embedded components can be re-translated in place without re-mounting: call `stripeConnectInstance.update({locale})` with the `locale` from a freshly created account session. Nothing is sent to the processor when this changes, because the processor holds no copy of it.다음에 생성하시는 계정 세션부터 적용됩니다. 이미 화면에 있는 컴포넌트는 초기화 시점의 언어를 유지하므로, 기본적으로 가맹점은 다음 페이지 로드에서 변경을 보게 됩니다. 더 빨리 반영하시려면, 새로 생성한 계정 세션의 `locale`로 `stripeConnectInstance.update({locale})`을 호출하시면 다시 마운트하지 않고도 컴포넌트가 제자리에서 번역됩니다. 처리사는 이 값을 보관하지 않으므로 변경 시 처리사로 보내는 것은 없습니다. nullable
One of다음 중 하나
|
business
optional |
object |
The business fields a partial update may touch.부분 수정으로 변경할 수 있는 사업 필드입니다. The identity fields to set or clear.설정하거나 삭제할 신원 필드입니다. |
business.legal_name
optional |
string |
Registered legal name, if it differs from `name`.등록된 법적 상호입니다. `name`과 다른 경우에 보내 주십시오. |
business.structure
optional |
enum |
The merchant's legal structure, in OutlinePay's processor-agnostic vocabulary (company only). See MerchantBusiness for what each maps to.OutlinePay의 처리사 독립 용어로 표현한 가맹점의 법적 형태입니다(법인 전용). 각 값의 대응은 MerchantBusiness를 참고해 주십시오.
One of다음 중 하나
|
business.url
optional |
string |
Public website: a full http(s) URL with a domain name, e.g. https://hanui.example. The processor additionally refuses placeholder and shared domains (example.com and the like) when it is attached.공개 웹사이트입니다. 도메인 이름을 포함한 완전한 http(s) URL이어야 합니다. 예: https://hanui.example. 자리표시용·공용 도메인(example.com 등)은 처리사 연결 시점에 처리사가 추가로 거부합니다. |
business.address
optional |
object |
|
business.address.line1
optional |
string |
|
business.address.line2
optional |
string |
|
business.address.city
optional |
string |
|
business.address.state
optional |
string |
Two-letter state or province code. For a US address, the USPS code. The processor cannot serve US insular areas (GU, VI, AS, MP).두 글자 주/도 코드입니다. 미국 주소는 USPS 코드를 사용하며, 미국 도서 지역(GU, VI, AS, MP)은 결제 처리사가 지원하지 않습니다. |
business.address.postal_code
optional |
string |
Postal code. For a US address, 5 digits or ZIP+4, e.g. 19104 or 19104-2617.우편번호입니다. 미국 주소는 5자리 또는 ZIP+4 형식입니다. 예: 19104, 19104-2617. |
business.address.country
optional |
string |
Two-letter ISO country code, required whenever an address is sent. This is the country of *this address*: a business address must be in the merchant's own country (the top-level `country` on the merchant), while a representative's home address may be anywhere.두 글자 ISO 국가 코드로, 주소를 보내실 때는 필수입니다. 이는 *이 주소*의 국가입니다. 사업장 주소는 가맹점 자신의 국가(가맹점의 최상위 `country`)에 있어야 하며, 대표자의 자택 주소는 어느 국가든 가능합니다. |
business.phone
optional merchant-owned |
string |
Business phone. Use E.164: '+', the country code, then the subscriber number, e.g. +12125550123 (US) or +821012345678 (KR). A phone no processor could parse is refused as a 400 invalid_request naming this field.사업자 전화번호입니다. E.164 형식('+', 국가 코드, 가입자 번호 순)을 사용해 주십시오. 예: +12125550123(미국), +821012345678(한국). 어떤 처리사도 해석할 수 없는 전화번호는 이 필드를 지목한 400 invalid_request로 거부됩니다. |
business.product_description
optional merchant-owned |
string |
One or two sentences on what the merchant sells.가맹점이 판매하는 상품에 대한 한두 문장의 설명입니다. |
business.industry_code
optional merchant-owned |
string |
Four-digit merchant category code (MCC) classifying what the business sells: the card networks' ISO 18245 standard, not ours. Common examples: 5399 general merchandise, 5812 restaurants, 5691 clothing, 5734 software. Omit it and the processor infers one from the website and product description. We accept the codes listed at https://outlinepay.com/docs/mccs and refuse any other value naming this field.사업체가 판매하는 품목을 분류하는 4자리 업종 코드(MCC)로, OutlinePay가 아니라 카드 네트워크의 ISO 18245 표준입니다. 흔한 예: 5399 종합 소매, 5812 음식점, 5691 의류, 5734 소프트웨어. 생략하시면 처리사가 웹사이트와 상품 설명으로 추정합니다. 지원 코드 목록 (https://outlinepay.com/docs/mccs)의 코드를 받으며, 그 외의 값은 이 필드를 지목해 거부됩니다. |
business.statement_descriptor
optional merchant-owned |
string |
What buyers see on their card statement. 5 to 22 characters, at least one Latin letter, no angle brackets. Keep it recognisable, or it drives chargebacks.구매자의 카드 명세서에 표시되는 문구입니다. 5~22자이고, 라틴 문자를 하나 이상 포함하며, 꺾쇠괄호는 쓸 수 없습니다. 알아보기 쉽게 정하지 않으면 지불 거절의 원인이 됩니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "PATCH", CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "business" => [ "url" => "https://acme.example", "legal_name" => "Acme Trading Co. LLC", ], ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X PATCH "https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "business": { "url": "https://acme.example", "legal_name": "Acme Trading Co. LLC" } }'
Response응답
Returns a Merchant.Merchant 객체를 반환합니다.
{
"id": "mrc_9f2c8bAaZ1kQ",
"object": "merchant",
"name": "Acme Trading Co.",
"email": "[email protected]",
"status": "active",
"mode": "test",
"entity_type": "company",
"business": {
"legal_name": "Acme Trading Co. LLC",
"structure": "llc",
"phone": "+12125550123",
"url": "https://acme.example",
"product_description": "Imported kitchenware and small appliances.",
"industry_code": "5722",
"statement_descriptor": "ACME TRADING",
"address": {
"line1": "1600 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19103",
"country": "US"
}
},
"processors": [
{
"processor": "stripe",
"account_id": "acct_1AbCdEfGhIjKlMnO",
"onboarding_completed": true,
"verified": true,
"representative_prefilled": true
}
],
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/merchants/{merchant_id}/processors
Attach a processor결제 처리사 연결
Opens the merchant's connected payment-processor account, the step that makes a merchant chargeable. Kept separate from Create a merchant so a merchant can exist before, and independently of, any processor.가맹점의 결제 처리사 연결 계정을 개설하며, 이 단계를 거쳐야 가맹점이 결제를 받을 수 있습니다. 가맹점이 어떤 결제 처리사보다 먼저, 그리고 처리사와 무관하게 존재할 수 있도록 가맹점 생성과 분리했습니다.
- Forward-only identity전달 전용 신원 정보
- This is where tax_id and the representative are supplied. We pass them to the processor and then discard them: never written down, never returned, so they cannot appear in a later GET, an event payload or a backup.tax_id와 representative를 전달하는 곳이 바로 이 단계입니다. 결제 처리사에 전달한 뒤 폐기하며, 기록하지도 반환하지도 않으므로 이후의 GET 응답이나 이벤트 페이로드, 백업에 나타날 수 없습니다.
- Why it is worth sending전달하실 때의 이점
- Combined with the business stored at creation, it takes a US company's onboarding from 15 outstanding requirements down to 4. The merchant is left with its bank account, the last four digits of the representative's national ID, and the terms of service.가맹점 생성 시 저장한 business와 함께 사용하면, 미국 법인의 온보딩 미충족 요건이 15개에서 4개로 줄어듭니다. 가맹점에는 은행 계좌, 대표자 주민등록번호 성격 식별자의 뒤 네 자리, 이용약관 동의만 남습니다.
- What happens next이후 진행
- The account is open but restricted, so this call does not make the merchant chargeable on its own: onboarding_completed and verified both come back false and status stays created. Create an account session next and render the onboarding component, which is where the processor collects what it still needs. Until that finishes, charges are refused with 409 merchant_not_onboarded.계정은 개설되었지만 제한된 상태이므로, 이 호출만으로 가맹점이 결제를 받을 수 있게 되지는 않습니다. onboarding_completed와 verified는 모두 false로 반환되고 status는 created로 유지됩니다. 다음으로 계정 세션을 생성해 온보딩 컴포넌트를 렌더링하시면, 결제 처리사가 아직 필요로 하는 항목을 그곳에서 수집합니다. 완료되기 전까지 결제는 409 merchant_not_onboarded로 거부됩니다.
- If the representative is rejected대표자가 거부된 경우
- For a company, opening the account and registering the representative are two steps at the processor, so a representative it refuses can arrive after the account has opened. The account then stays attached: the 400 says so, and the merchant lists the processor with representative_prefilled false. Send the same request again with a corrected representative. The open account is reused, so retries never create a second one. The retry reads only the representative: the stored business went with the account when it opened, and a tax_id it did not carry is collected during onboarding.법인의 경우 처리사 쪽에서 계정 개설과 대표자 등록이 두 단계로 이루어지므로, 계정이 열린 뒤에 대표자가 거부될 수 있습니다. 이때 계정은 연결된 상태로 유지됩니다. 400 응답이 이를 알려주며, 가맹점의 processors 항목에 representative_prefilled가 false로 표시됩니다. 수정한 representative와 함께 같은 요청을 다시 보내 주십시오. 열린 계정을 재사용하므로 재시도로 계정이 하나 더 생기지 않습니다. 재시도에서는 representative만 읽습니다. 저장된 business는 계정이 열릴 때 함께 전달되었고, 전달되지 않은 tax_id는 온보딩에서 수집됩니다.
- Already attached이미 연결된 경우
- A merchant that already has an account for the given processor comes back as a 409, unless that account is still waiting for its representative, which resumes instead. The 409 names the state it found.해당 결제 처리사의 계정을 이미 보유한 가맹점은 409로 반환됩니다. 다만 그 계정이 아직 대표자를 기다리는 경우에는 409 대신 대표자 등록을 이어서 진행합니다. 409는 발견한 상태를 그대로 알려줍니다.
- Default rail기본 결제 경로
- The first processor a merchant attaches becomes its default_processor, used whenever a charge names none. It does not change on its own when you attach another.가맹점이 처음 연결한 결제 처리사가 default_processor가 되며, 결제 시 처리사를 지정하지 않으면 이 처리사가 사용됩니다. 이후 다른 처리사를 연결해도 자동으로 바뀌지 않습니다.
Conventions규약 Forward-only fields전달 전용 필드·Onboarding is required before charging결제 전 온보딩 필수
Emits이벤트 발행
merchant.updated
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
merchant_idrequired |
path |
string |
The merchant id.가맹점 id입니다. |
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
processor
optional |
string |
Which processor to attach. Currently only `stripe`.연결할 결제 처리사입니다. 현재는 `stripe`만 지원합니다. |
tax_id
optional forward-only |
string |
Business tax identifier: the EIN for a US business (nine digits, e.g. 12-3456789). Sent to the processor to satisfy its verification.사업자 세금 식별 번호이며, 미국 사업체는 EIN(숫자 9자리, 예: 12-3456789)입니다. 처리사의 검증을 충족하기 위해 전달합니다. |
representative
optional forward-only |
object |
The person who controls the business. Every field here is forward-only: we pass it to the processor so onboarding stops asking, and keep none of it. Do not send a national ID (SSN); the processor collects that from the merchant directly, and supplying it satisfies nothing.사업체를 지배하는 사람입니다. 이곳의 모든 필드는 전달 전용입니다. 온보딩에서 다시 묻지 않도록 처리사에 전달하고 아무것도 보관하지 않습니다. 국가 신분 번호(SSN)는 보내지 마십시오. 처리사가 가맹점에게서 직접 수집하며, 제공하셔도 아무것도 충족되지 않습니다. |
representative.first_name
optional forward-only |
string |
|
representative.last_name
optional forward-only |
string |
|
representative.email
optional forward-only |
string |
|
representative.phone
optional forward-only |
string |
Use E.164: '+', the country code, then the subscriber number, e.g. +12125550123 (US) or +821012345678 (KR). A phone no processor could parse is refused as a 400 invalid_request naming this field.E.164 형식('+', 국가 코드, 가입자 번호 순)을 사용해 주십시오. 예: +12125550123(미국), +821012345678(한국). 어떤 처리사도 해석할 수 없는 전화번호는 이 필드를 지목한 400 invalid_request로 거부됩니다. |
representative.date_of_birth
optional forward-only |
string |
ISO 8601 date, YYYY-MM-DD, e.g. 1985-04-27. Must be a past date at least 13 years back, the processor's minimum age for a representative.ISO 8601 날짜(YYYY-MM-DD) 형식입니다. 예: 1985-04-27. 최소 13년 전의 과거 날짜여야 하며, 이는 결제 처리사가 요구하는 대표자의 최소 연령입니다. |
representative.address
optional forward-only |
object |
The representative's home address.대표자의 자택 주소입니다. |
representative.address.line1
optional forward-only |
string |
|
representative.address.line2
optional forward-only |
string |
|
representative.address.city
optional forward-only |
string |
|
representative.address.state
optional forward-only |
string |
Two-letter state or province code. For a US address, the USPS code. The processor cannot serve US insular areas (GU, VI, AS, MP).두 글자 주/도 코드입니다. 미국 주소는 USPS 코드를 사용하며, 미국 도서 지역(GU, VI, AS, MP)은 결제 처리사가 지원하지 않습니다. |
representative.address.postal_code
optional forward-only |
string |
Postal code. For a US address, 5 digits or ZIP+4, e.g. 19104 or 19104-2617.우편번호입니다. 미국 주소는 5자리 또는 ZIP+4 형식입니다. 예: 19104, 19104-2617. |
representative.address.country
optional forward-only |
string |
Two-letter ISO country code, required whenever an address is sent. This is the country of *this address*: a business address must be in the merchant's own country (the top-level `country` on the merchant), while a representative's home address may be anywhere.두 글자 ISO 국가 코드로, 주소를 보내실 때는 필수입니다. 이는 *이 주소*의 국가입니다. 사업장 주소는 가맹점 자신의 국가(가맹점의 최상위 `country`)에 있어야 하며, 대표자의 자택 주소는 어느 국가든 가능합니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ/processors"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "tax_id" => "00-0000000", "representative" => [ "first_name" => "Dana", "last_name" => "Whitfield", "email" => "[email protected]", "phone" => "+12125550188", "date_of_birth" => "1985-04-27", "address" => [ "line1" => "220 Spruce St", "city" => "Philadelphia", "state" => "PA", "postal_code" => "19106", "country" => "US", ], ], ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ/processors" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "tax_id": "00-0000000", "representative": { "first_name": "Dana", "last_name": "Whitfield", "email": "[email protected]", "phone": "+12125550188", "date_of_birth": "1985-04-27", "address": { "line1": "220 Spruce St", "city": "Philadelphia", "state": "PA", "postal_code": "19106", "country": "US" } } }'
Response응답
Returns a Merchant.Merchant 객체를 반환합니다.
{
"id": "mrc_9f2c8bAaZ1kQ",
"object": "merchant",
"name": "Acme Trading Co.",
"email": "[email protected]",
"status": "created",
"mode": "test",
"entity_type": "company",
"business": {
"legal_name": "Acme Trading Co. LLC",
"structure": "llc",
"phone": "+12125550123",
"url": "https://acme.example",
"product_description": "Imported kitchenware and small appliances.",
"industry_code": "5722",
"statement_descriptor": "ACME TRADING",
"address": {
"line1": "1600 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19103",
"country": "US"
}
},
"processors": [
{
"processor": "stripe",
"account_id": "acct_1AbCdEfGhIjKlMnO",
"onboarding_completed": false,
"verified": false,
"representative_prefilled": true
}
],
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/merchants/{id}/account_session
Create an account session계정 세션 생성
Returns a short-lived client_secret your page hands to the processor's embedded components, plus the publishable key and the merchant's locale. Your server is the authorization gate. It decides which logged-in merchant a session is for. See `components` below for the full set, named in OutlinePay's own vocabulary rather than the processor's.귀사의 페이지가 결제 처리사의 임베드 컴포넌트에 전달할 단기 client_secret과 공개 키, 그리고 가맹점의 locale을 반환합니다. 어느 로그인 가맹점을 위한 세션인지 판단하는 인가 주체는 귀사의 서버입니다. 전체 목록은 아래 components를 참고해 주십시오. 처리사의 이름이 아니라 OutlinePay의 용어로 표기되어 있습니다.
This is the step that makes an attached merchant chargeable: the onboarding component is the only place a merchant completes its verification, so nothing can be charged until it has been rendered and finished. See the Quickstart for a worked example of both halves.연결된 가맹점이 실제로 결제를 받을 수 있게 되는 단계가 바로 이 단계입니다. 가맹점의 검증은 오직 온보딩 컴포넌트 안에서만 완료되므로, 이 컴포넌트를 렌더링해 완료하기 전까지는 어떤 결제도 받을 수 없습니다. 양쪽 구현 예시는 시작하기 가이드를 참고해 주십시오.
- Attach a processor first결제 처리사를 먼저 연결하십시오
- A session is scoped to the merchant's connected account, so it needs one to exist. Without it this returns 400 invalid_request, "This merchant has no processor yet. Attach one first."세션은 가맹점의 연결 계정을 대상으로 하므로, 해당 계정이 먼저 존재해야 합니다. 연결되어 있지 않으면 400 invalid_request와 함께 "This merchant has no processor yet. Attach one first."를 반환합니다.
- What to do with the client_secretclient_secret 사용 방법
- Hand it back to your own page and give it to the processor's SDK, then create the onboarding component. Two machines, two calls: your server makes this call so your secret key never reaches the browser, and your page asks an endpoint of yours for the secret.반환된 값을 귀사의 페이지로 전달하고, 이를 결제 처리사의 SDK에 넘긴 뒤 온보딩 컴포넌트를 생성하십시오. 서버와 브라우저, 두 곳에서 각각 한 번씩 호출합니다. 이 호출은 귀사의 서버가 수행하므로 시크릿 키가 브라우저에 노출되지 않으며, 페이지는 귀사의 엔드포인트에 secret을 요청합니다.
- It expires, so mint a fresh one every time만료되므로 매번 새로 발급하십시오
- The session is short-lived and the SDK asks for a new secret by itself when it lapses mid-form, which is why it takes a function rather than a string. Point that function at an endpoint that calls this one afresh. Handing back a cached secret strands the merchant partway through onboarding.세션은 유효 기간이 짧고, 양식 작성 중 만료되면 SDK가 스스로 새 secret을 요청합니다. 문자열이 아니라 함수를 받는 이유가 바로 이것입니다. 해당 함수는 이 엔드포인트를 매번 새로 호출하는 귀사의 엔드포인트를 가리키게 해 주십시오. 캐시된 secret을 반환하면 가맹점이 온보딩 도중에 멈추게 됩니다.
- Do not send an Idempotency-KeyIdempotency-Key를 보내지 마십시오
- Idempotency keys are ignored here: a replayed response would carry an expired client_secret, and creating a second session is harmless.이 엔드포인트에서 Idempotency-Key는 무시됩니다. 저장된 응답을 재생하면 이미 만료된 client_secret이 전달되고, 세션이 두 번 생성되어도 아무런 문제가 없기 때문입니다.
- How you know onboarding finished온보딩 완료 확인 방법
- processors[].onboarding_completed turns true when the merchant submits, and processors[].verified turns true when the processor accepts. The merchant's status turns active at that moment and we emit merchant.updated. The component's own callbacks mean the form closed, not that the merchant was accepted, so read the merchant.가맹점이 제출하면 processors[].onboarding_completed가 true가 되고, 결제 처리사가 승인하면 processors[].verified가 true가 됩니다. 이 시점에 가맹점의 status가 active로 바뀌고 merchant.updated 이벤트를 발송합니다. 컴포넌트 자체의 콜백은 양식이 닫혔다는 뜻일 뿐 승인되었다는 뜻이 아니므로, 가맹점 객체를 확인해 주십시오.
- Never refused for a merchant that has not onboarded온보딩 전 가맹점도 거부되지 않습니다
- Unlike the charge endpoints, this one is deliberately not gated. It is the way out of a 409 merchant_not_onboarded, so gating it would leave a merchant that has never onboarded unable to ever onboard.결제 엔드포인트와 달리 이 엔드포인트에는 의도적으로 제한을 두지 않았습니다. 409 merchant_not_onboarded를 해결하는 경로가 바로 이 엔드포인트이므로, 여기에 제한을 두면 온보딩을 시작하지 않은 가맹점은 영원히 온보딩할 수 없게 됩니다.
- The onboarding component shows our merchant terms firstThe onboarding component shows our merchant terms first
- When the response's terms.required is true, outlinepay.js frames terms.url ahead of the processor's form and the merchant accepts the OutlinePay merchant terms there, once, for every processor. You build nothing and record nothing. The merchant object's terms_acceptance and a merchant.updated event tell your systems it happened. If your Content-Security-Policy sets frame-src, allow the origin of terms.url.When the response's terms.required is true, outlinepay.js frames terms.url ahead of the processor's form and the merchant accepts the OutlinePay merchant terms there, once, for every processor. You build nothing and record nothing. The merchant object's terms_acceptance and a merchant.updated event tell your systems it happened. If your Content-Security-Policy sets frame-src, allow the origin of terms.url.
Conventions규약 Onboarding is required before charging결제 전 온보딩 필수·Processor-agnostic values프로세서 독립 값
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The merchant id.가맹점 id입니다. |
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
components
required |
array<string> |
Which components to scope the session to, in OutlinePay's processor-agnostic vocabulary. Required: a session grants exactly what you name here, so name only what the page mounts. Note: your browser still mounts each one with the processor's own SDK (for Stripe, Connect.js), which uses its own component ids.세션의 범위를 지정할 컴포넌트이며, OutlinePay의 처리사 독립 용어입니다. 필수 항목입니다. 세션은 여기에 지정하신 컴포넌트만 정확히 허용하므로, 페이지가 마운트하는 것만 지정해 주십시오. 참고로 브라우저에서는 여전히 처리사 자신의 SDK(Stripe는 Connect.js)로 각 컴포넌트를 마운트하며, SDK는 자체 컴포넌트 id를 사용합니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ/account_session"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "components" => [ "onboarding", ], ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/merchants/mrc_9f2c8bAaZ1kQ/account_session" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "components": [ "onboarding" ] }'
Response응답
| Field필드 | Type타입 | Description설명 |
|---|---|---|
object
|
string |
The literal string "account_session".고정 문자열 "account_session"입니다. |
processor
|
string |
The processor these credentials belong to, e.g. "stripe".이 자격 증명이 속한 결제 처리사입니다. 예: "stripe". |
client_secret
|
string |
|
publishable_key
|
string |
|
components
|
array<string> |
|
locale
|
string |
The merchant's language, spelled the way this processor's SDK wants it. Pass it straight through when you initialise the components. It is not the tag you sent us on the merchant: Stripe's embedded components accept only regional codes, so a merchant stored as `ko` comes back here as `ko-KR`, and a language the SDK cannot render falls back to `en-US` rather than failing. Setting the merchant's locale alone does not translate the form; the SDK has to be told.가맹점의 언어를 이 처리사의 SDK가 원하는 표기로 반환합니다. 컴포넌트를 초기화하실 때 그대로 전달해 주십시오. 가맹점에 보내신 태그와는 다릅니다. Stripe의 임베드 컴포넌트는 지역 코드만 허용하므로 `ko`로 저장된 가맹점은 여기서 `ko-KR`로 반환되고, SDK가 렌더링할 수 없는 언어는 실패하는 대신 `en-US`로 대체됩니다. 가맹점의 locale 설정만으로는 양식이 번역되지 않으며, SDK에 알려 주어야 합니다. |
terms
|
object |
Whether this merchant still has to accept the OutlinePay merchant terms, and where they are shown. outlinepay.js reads this on its own: when `required` is true, mounting the onboarding component shows the terms screen at `url` first, and the processor's form after the merchant agrees. Nothing to build on your side. Keep forwarding this response body verbatim. `url` is short-lived and scoped to this one merchant, minted fresh with every session. If your Content-Security-Policy sets frame-src, allow the origin of `url`, the same way script-src already allows the processor's SDK host.이 가맹점이 아직 OutlinePay 가맹점 약관에 동의해야 하는지, 그리고 약관이 어디에 표시되는지를 담습니다. outlinepay.js가 스스로 읽는 값으로, `required`가 true이면 온보딩 컴포넌트를 마운트할 때 `url`의 약관 화면이 먼저 표시되고 가맹점이 동의한 뒤 결제 처리사의 양식이 나타납니다. 귀사가 구현할 것은 없으며, 이 응답 본문을 지금처럼 그대로 전달해 주시면 됩니다. `url`은 수명이 짧고 이 가맹점 하나에만 유효하며 세션을 발급할 때마다 새로 생성됩니다. Content-Security-Policy에 frame-src를 설정하셨다면 script-src에 결제 처리사의 SDK 호스트를 허용하신 것과 같은 방식으로 `url`의 오리진을 허용해 주십시오. |
terms.required
|
boolean |
True until the merchant has accepted the current terms version.가맹점이 현재 약관 버전에 동의하기 전까지 true입니다. |
terms.url
|
string |
The terms screen to frame, or null when required is false.프레임으로 표시할 약관 화면이며, required가 false이면 null입니다. nullable |
{
"object": "account_session",
"processor": "stripe",
"client_secret": "accs_secret_9f2c8b...",
"publishable_key": "pk_test_51...",
"components": [
"onboarding"
],
"locale": "ko-KR",
"terms": {
"required": true,
"url": "https://outlinepay.com/embedded/merchant-terms?token=eyJfcmFpbHMi..."
}
}
Object객체
The Payment objectPayment 객체
A single charge. Creation returns a hosted checkout_url; the outcome arrives by webhook.한 건의 결제입니다. 생성 시 호스팅 checkout_url이 반환되며, 결과는 웹훅으로 전달됩니다.
Lifecycle · card, wallet, bnpl상태 흐름 · card, wallet, bnpl
awaiting_payment ---------------------> succeeded
|
'--------------------> expired
Instant methods settle at checkout, so there are only two ways out: the customer completes the payment (succeeded), or the checkout lapses at expires_at (expired). A declined card does not fail the payment. The customer just retries on the checkout page, so the payment stays awaiting_payment until one of the two.즉시 확정 수단은 체크아웃 시점에 결제가 확정되므로 결과는 두 가지뿐입니다. 고객이 결제를 완료하면 succeeded, 체크아웃이 expires_at에 만료되면 expired입니다. 카드 승인 거절은 결제를 실패시키지 않습니다. 고객이 체크아웃 페이지에서 다시 시도할 뿐이므로, 둘 중 하나가 되기 전까지 결제는 awaiting_payment로 유지됩니다.
Lifecycle · bank_debit, bank_transfer상태 흐름 · bank_debit, bank_transfer
awaiting_payment ----> processing ----> succeeded
| |
'--> expired '--------> failed
Bank rails settle after the customer finishes, so a third state sits in the middle: processing means paid but not settled, and it can last days (an ACH debit takes up to four business days, longer on microdeposit verification). Do not fulfill on processing. failed is genuinely reachable here, after the customer has done everything right. failure_reason says why and what to do next.은행 결제는 고객이 결제를 마친 뒤에 정산되므로 중간에 상태가 하나 더 있습니다. processing은 결제는 되었지만 아직 정산되지 않았다는 뜻이며, 며칠간 지속될 수 있습니다(ACH 출금은 영업일 기준 최대 4일, 소액 입금 검증 시 더 길어집니다). processing 상태에서 상품을 발송하지 마십시오. 이 흐름에서는 고객이 모든 절차를 마친 뒤에도 failed가 실제로 발생할 수 있으며, 원인과 다음 조치는 failure_reason에 담깁니다.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "payment", naming this resource's type. Every resource carries one, and it is the discriminator for an event's `data`.고정 문자열 "payment"로, 이 리소스의 타입을 나타냅니다. 모든 리소스가 이 필드를 가지며, 이벤트 `data`의 판별자이기도 합니다. |
status
|
enum |
Where the payment is. Both lifecycles are drawn under The Payment object.결제가 어느 단계에 있는지입니다. 두 상태 흐름 모두 The Payment object 아래에 그림으로 정리되어 있습니다. `awaiting_payment`: the customer has not finished. A declined card does not end this state; the customer simply retries on the checkout page.`awaiting_payment`: 고객이 아직 결제를 마치지 않았습니다. 카드 승인 거절은 이 상태를 끝내지 않으며, 고객이 체크아웃 페이지에서 다시 시도할 뿐입니다. `processing`: the customer has paid but the money is still moving. Only delayed methods (bank_debit, bank_transfer) reach it, it can last days, and nothing is decided yet, so do not fulfill on it.`processing`: 고객은 결제했지만 자금이 아직 이동 중입니다. 지연 정산 수단(bank_debit, bank_transfer)만 이 상태에 도달하며, 며칠간 지속될 수 있고 아직 아무것도 확정되지 않았으므로 이 상태에서 상품을 발송하지 마십시오. `failed`: reachable only from `processing`, so only on delayed methods. `failure_reason` says why.`failed`: `processing`에서만 도달하므로 지연 정산 수단에서만 발생합니다. 원인은 `failure_reason`에 담깁니다.
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
merchant_id
|
string |
|
amount
|
integer |
Minor units of `currency` (for usd, cents).`currency`의 최소 단위 정수입니다(usd는 센트). |
currency
|
enum |
What the customer was charged in. `usd` is the only currency we support today.고객에게 청구된 통화입니다. 현재 지원 통화는 `usd`뿐입니다.
One of다음 중 하나
|
description
|
string |
nullable |
customer
|
object |
The customer details you sent at creation, echoed in the same shape. Null when you sent none.생성 시 보내신 고객 정보를 같은 형태로 반환합니다. 보내지 않으셨다면 null입니다. nullable |
customer.email
|
string |
|
fees
|
object |
Fees charged on the gross amount, in minor units. Refunds do not return fees.총액 기준으로 부과된 수수료이며 최소 단위입니다. 환불 시에도 수수료는 반환되지 않습니다. `outline` and `partner` are frozen as soon as they are knowable, which for almost every payment is creation time. A later rate change does not touch them.`outline`과 `partner`는 확정 가능해지는 즉시 고정되며, 대부분의 결제에서는 생성 시점입니다. 이후의 요율 변경은 영향을 주지 않습니다. The exception is a checkout whose fee depends on which method the customer picks (a capped bank rail offered beside an uncapped one). There, `outline` and `partner` stay null until the customer answers on the hosted checkout page; `selected_payment_method` tells you whether they have. A payment that expires unanswered keeps null forever: no method was chosen and no money moved, so no fee was ever charged.예외는 고객이 선택하는 수단에 따라 수수료가 달라지는 체크아웃입니다(상한이 있는 은행 수단을 상한 없는 수단과 함께 제공하는 경우). 이때 `outline`과 `partner`는 고객이 호스팅 체크아웃 페이지에서 답할 때까지 null로 유지되며, 답했는지는 `selected_payment_method`로 알 수 있습니다. 답 없이 만료된 결제는 계속 null입니다. 수단도 선택되지 않았고 자금도 이동하지 않았으므로 수수료도 부과된 적이 없습니다. |
fees.processor
|
integer |
The processor's own cut, read from the charge's balance transactions (see the top-level `processor` field for which processor).결제 처리사 자신의 몫으로, 결제 건의 잔액 거래에서 읽어 옵니다(어느 처리사인지는 최상위 `processor` 필드 참고). Null until captured, a moment after the outcome. That means it is still null on the payment.succeeded or payment.failed event; the payment.updated event that follows carries it.확정 전까지 null이며, 결과 직후에 확정됩니다. 따라서 payment.succeeded나 payment.failed 이벤트 시점에는 아직 null이고, 뒤따르는 payment.updated 이벤트에 담겨 옵니다. Set on failed payments too. There it is the processor's flat charge for a returned bank debit, and the only fee borne: a failed payment collects nothing for OutlinePay or for you.실패한 결제에도 설정됩니다. 이때는 반환된 은행 출금에 대한 처리사의 정액 수수료이며, 유일하게 부과되는 수수료입니다. 실패한 결제에서는 OutlinePay도 귀사도 아무것도 수취하지 않습니다. nullable |
fees.outline
|
integer |
OutlinePay's fee, from the rate card. Same in test and live.OutlinePay의 수수료로, 요율표 기준입니다. 테스트와 라이브가 동일합니다. Null while a method choice is still outstanding. 0 on a payment that failed or expired, because the processor returns this fee when a debit is returned.수단 선택이 남아 있는 동안은 null입니다. 실패하거나 만료된 결제에서는 0입니다. 출금이 반환되면 처리사가 이 수수료를 돌려주기 때문입니다. nullable |
fees.partner
|
integer |
Your fee, at your configured rate.귀사의 수수료로, 설정하신 요율이 적용됩니다. Null while a method choice is still outstanding. 0 on a payment that failed or expired: nothing was collected, so nothing accrues to you.수단 선택이 남아 있는 동안은 null입니다. 실패하거나 만료된 결제에서는 0입니다. 수취된 금액이 없으므로 귀사에 귀속되는 금액도 없습니다. nullable |
fees.dispute
|
integer |
What the disputes on this payment cost, summed: the same money that is itemised per-dispute on disputes[].fee. 0 when there are none.이 결제의 분쟁에 든 비용의 합계로, disputes[].fee에 건별로 표시되는 것과 같은 금액입니다. 분쟁이 없으면 0입니다. |
fees.invoice
|
integer |
What the payment processor charged the merchant for issuing the invoice, on a payment created with `invoice.enabled`. Null on every payment that did not ask for one.`invoice.enabled`로 생성된 결제에서, 결제 처리사가 인보이스 발행 대가로 가맹점에 부과한 금액입니다. 인보이스를 요청하지 않은 결제에서는 항상 null입니다. Live mode only. It is also null on an invoiced payment until the figure lands, which is a day or so behind the payment, and it stays null forever in test mode: the processor's itemised fee reporting does not cover test data at all. We never estimate it from a published rate, because a computed number sitting beside measured ones would be indistinguishable from them.라이브 모드에서만 제공됩니다. 인보이스를 요청한 결제에서도 금액이 확정되기 전에는 null이며, 확정까지는 결제 시점보다 하루 정도 걸립니다. 테스트 모드에서는 계속 null로 남습니다. 처리사의 수수료 상세 리포트가 테스트 데이터를 전혀 다루지 않기 때문입니다. 공개된 요율로 추정하지는 않습니다. 실제로 측정된 값 옆에 계산된 값이 놓이면 둘을 구분할 수 없기 때문입니다. nullable |
fees.total
|
integer |
Every fee borne on this payment: the sum of the five fields above it (processor + outline + partner + dispute + invoice).이 결제에 부과된 모든 수수료로, 바로 위 다섯 필드의 합입니다(processor + outline + partner + dispute + invoice). Counts an uncaptured processor fee as 0. Null while a method choice is outstanding, since a figure there would read as a quote.아직 확정되지 않은 처리사 수수료는 0으로 계산합니다. 수단 선택이 남아 있는 동안은 null입니다. 그 시점의 숫자는 견적처럼 읽히기 때문입니다. nullable |
merchant_net
|
integer |
The merchant's net: `amount − fees.total`.가맹점의 순수령액입니다. `amount − fees.total`. Reads high until the processor's fee lands, a moment after the outcome, including on the payment.succeeded event itself. Record net from the payment.updated event that follows.처리사 수수료가 확정되기 전까지는 실제보다 높게 읽히며, payment.succeeded 이벤트 시점도 마찬가지입니다. 순수령액은 뒤따르는 payment.updated 이벤트 기준으로 기록해 주십시오. Null while a method choice is outstanding, alongside fees.total.수단 선택이 남아 있는 동안은 fees.total과 함께 null입니다. Can go negative. A full refund keeps all fees. On a payment that failed or expired there is no principal at all, so this is the negative of the processor's charge for the failure (its flat fee for a returned bank debit), and 0 until that charge has been read.음수가 될 수 있습니다. 전액 환불 시에도 수수료는 모두 유지됩니다. 실패하거나 만료된 결제에는 원금 자체가 없으므로, 실패에 대해 처리사가 부과한 금액(반환된 은행 출금에 대한 정액 수수료)의 음수가 되며, 그 금액을 읽어 오기 전까지는 0입니다. nullable |
amount_refunded
|
integer |
Sum of non-failed refunds, in minor units.실패하지 않은 환불의 합계이며 최소 단위입니다. |
amount_refundable
|
integer |
amount − amount_refunded: headroom for a further refund. Reaches 0 at a full refund, and is 0 on any payment that did not settle, since only a succeeded payment can be refunded. Also 0 while a dispute is holding the money (disputes[].amount_withheld above zero), which the processor refuses to refund whether the dispute is open or already lost; it becomes refundable again if the dispute is won.amount − amount_refunded: 추가로 환불할 수 있는 여유분입니다. 전액 환불 시 0이 되고, 정산되지 않은 결제에서도 0입니다. succeeded인 결제만 환불할 수 있기 때문입니다. 분쟁이 자금을 보류 중인 동안(disputes[].amount_withheld가 0 초과)에도 0입니다. 분쟁이 진행 중이든 이미 패소했든 처리사가 환불을 거부하며, 승소하면 다시 환불 가능해집니다. |
refunds
|
array<object> |
Refunds against this payment, oldest first.이 결제에 대한 환불 목록이며 오래된 순입니다. |
refunds[].id
|
string |
|
refunds[].status
|
enum |
One of다음 중 하나
|
refunds[].amount
|
integer |
Minor units.최소 단위입니다. |
refunds[].metadata
|
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
refunds[].created_at
|
string |
ISO 8601 UTC.ISO 8601 UTC 형식입니다. |
disputes
|
array<object> |
Chargebacks against this payment, oldest first. Usually empty.이 결제에 대한 지불 거절 목록이며 오래된 순입니다. 보통은 비어 있습니다. |
disputes[].id
|
string |
|
disputes[].status
|
enum |
The chargeback's state, in OutlinePay's vocabulary and translated from whichever processor reported it. The `inquiry_*` set is the card networks' early retrieval request, raised before a formal chargeback; the rest is the real lifecycle, terminating in `won`/`lost`, or `refunded` when the merchant refunds instead of contesting.지불 거절의 상태로, OutlinePay의 용어이며 어느 처리사가 보고했든 변환되어 있습니다. `inquiry_*` 계열은 정식 지불 거절 전에 제기되는 카드 네트워크의 사전 조회 요청이고, 나머지가 실제 라이프사이클입니다. `won`/`lost`로 끝나거나, 가맹점이 다투는 대신 환불하면 `refunded`가 됩니다.
One of다음 중 하나
|
disputes[].reason
|
enum |
Why the cardholder disputed, in OutlinePay's vocabulary. Reason codes originate with the card networks but each processor normalises them differently, so we publish one set and fold theirs into it: bank_error covers the several ways a bank can decline to move the money, and anything we cannot place maps to other.카드 소지자가 지불 거절을 제기한 사유로, OutlinePay의 용어입니다. 사유 코드는 카드 네트워크에서 나오지만 처리사마다 다르게 정리하므로, 하나의 집합으로 공개하고 처리사의 값을 그 안으로 접습니다. bank_error는 은행이 자금 이동을 거절하는 여러 경우를 묶은 값이고, 분류할 수 없는 값은 other로 대응됩니다. nullable Accepted values (10)허용 값 (10개) |
disputes[].amount
|
integer |
Minor units.최소 단위입니다. |
disputes[].fee
|
integer |
What the processor charged the merchant to handle this dispute, in minor units (Stripe bills a flat 15.00 USD). Charged whether the dispute is won or lost. It is reported here rather than under the payment's fees because that is where the processor books it too, but the payment's fees.total and merchant_net both account for it.이 분쟁의 처리 대가로 처리사가 가맹점에 청구한 금액이며 최소 단위입니다(Stripe는 정액 15.00 USD). 승패와 무관하게 청구됩니다. 처리사도 이 수수료를 분쟁 쪽에 기록하므로 결제의 fees가 아니라 여기에 표시하지만, 결제의 fees.total과 merchant_net에는 모두 반영됩니다. nullable |
disputes[].amount_withheld
|
integer |
How much of the payment the processor is currently holding back over this dispute, in minor units. Equal to amount from the moment a dispute opens, and 0 once the merchant wins. While it is above zero the payment cannot be refunded and amount_refundable reads 0.이 분쟁으로 처리사가 현재 보류 중인 결제 금액이며 최소 단위입니다. 분쟁이 열리는 순간부터 amount와 같고, 가맹점이 승소하면 0이 됩니다. 0보다 큰 동안에는 결제를 환불할 수 없으며 amount_refundable이 0으로 표시됩니다. nullable |
disputes[].evidence_due_at
|
string |
Deadline to submit evidence, ISO 8601 UTC.증빙 제출 기한이며 ISO 8601 UTC 형식입니다. nullable |
disputes[].created_at
|
string |
ISO 8601 UTC.ISO 8601 UTC 형식입니다. |
processor
|
string |
The underlying processor, e.g. "stripe".기반 결제 처리사입니다. 예: "stripe". |
processor_payment_method
|
string |
What actually settled, in the processor's own vocabulary (for example "card" or "us_bank_account"). Deliberately not one of OutlinePay's `payment_methods` categories: the `processor_` prefix marks a value as the processor's own and outside our portability contract, so read it for display or for reconciling against your processor, but do not branch product logic on it.실제로 정산된 수단으로, 처리사 자신의 용어입니다(예: "card", "us_bank_account"). 의도적으로 OutlinePay의 `payment_methods` 분류가 아닙니다. `processor_` 접두사는 처리사 고유의 값이며 이식성 계약 밖에 있다는 표시이므로, 표시 용도나 처리사와의 대사에는 읽어 쓰시되 제품 로직의 분기에는 사용하지 마십시오. Null until the charge exists, which for a delayed method such as ACH is days after the payment was created. It is read off the charge at the same moment as `fees.processor` and arrives on the same `payment.updated` event.결제 건이 생기기 전까지 null이며, ACH 같은 지연 수단에서는 결제 생성 후 며칠 뒤입니다. `fees.processor`와 같은 순간에 읽혀 같은 `payment.updated` 이벤트로 도착합니다. One value is less specific than it looks: `link` covers anything paid through the processor's wallet, including a bank account paid through it, so it does not tell you whether a card was involved. Use it for reconciliation against the processor, which is what it is for, rather than as a signal about how the customer funded the payment.한 값은 보기보다 덜 구체적입니다. `link`는 처리사의 지갑을 통해 결제된 모든 경우를 포괄하며 지갑을 통한 은행 계좌 결제도 포함하므로, 카드 사용 여부를 알려 주지 않습니다. 본래 용도인 처리사와의 대사에 사용하시고, 고객의 결제 재원에 대한 신호로는 사용하지 마십시오. nullable |
selected_payment_method
|
enum |
A payment-method category a partner may offer, in OutlinePay's vocabulary, translated to the processor's own methods at the boundary.파트너가 제공할 수 있는 결제 수단 분류로, OutlinePay의 용어이며 경계에서 처리사의 수단으로 변환됩니다. `card` is debit and credit cards. The card-based wallets (Apple Pay, Google Pay, Link) ride along automatically and cannot be offered without cards. `wallet` is the standalone wallets (Cash App, Amazon Pay). `bnpl` is buy-now-pay-later (Klarna, Affirm, Afterpay). `bank_debit` is ACH Direct Debit, paid from a US bank account. `bank_transfer` is a push transfer: the customer is shown a virtual account number and sends the funds from their own bank.`card`는 체크카드와 신용카드입니다. 카드 기반 간편결제(Apple Pay, Google Pay, Link)는 자동으로 함께 제공되며 카드 없이는 제공할 수 없습니다. `wallet`은 독립형 간편결제(Cash App, Amazon Pay)입니다. `bnpl`은 후불 결제(Klarna, Affirm, Afterpay)입니다. `bank_debit`은 미국 은행 계좌에서 출금하는 ACH Direct Debit입니다. `bank_transfer`는 입금 방식입니다. 고객에게 가상계좌 번호가 표시되고, 고객이 자신의 은행에서 자금을 보냅니다. The two bank rails behave differently from the rest. They settle after the customer finishes, so the payment sits in `processing` first, for days if the transfer is slow, and `bank_debit` can genuinely reach `failed`. Both OutlinePay's fee and yours are capped on them, so offering one beside an uncapped method sends the customer to a page asking which they intend to use before the price is fixed.두 은행 결제 수단은 나머지와 다르게 동작합니다. 고객이 결제를 마친 뒤에 정산되므로 결제가 먼저 `processing`에 머무르며, 이체가 늦으면 며칠간 지속될 수 있고, `bank_debit`은 실제로 `failed`에 도달할 수 있습니다. OutlinePay 수수료와 귀사 수수료 모두 상한이 적용되므로, 상한 없는 수단과 함께 제공하면 가격이 확정되기 전에 고객이 사용할 수단을 묻는 페이지가 표시됩니다. `bank_transfer` additionally requires `customer.email` at creation (the virtual account number and any refund follow a named buyer, and the same buyer keeps the same account number across payments), cannot be offered on a payment link, and is available to US merchants only for now. See "Payment methods" under Conventions.`bank_transfer`는 추가 조건이 있습니다. 생성 시 `customer.email`이 필요하고(가상계좌 번호와 환불은 특정 구매자를 따라가며, 같은 구매자는 결제할 때마다 같은 계좌번호를 사용합니다), 결제 링크에서는 제공할 수 없으며, 현재는 미국 가맹점만 이용할 수 있습니다. Conventions의 "Payment methods"를 참고해 주십시오. Provide an array to offer exactly those categories, nothing else. Omit the field and you get the documented default of `["card", "wallet"]`.배열을 지정하시면 정확히 그 분류만 제공됩니다. 생략하시면 문서화된 기본값 `["card", "wallet"]`이 적용됩니다. Which of the offered categories this payment will use. Set when the customer answered a choice OutlinePay put to them, which happens on the checkout where their answer is what fixes the fee (a capped bank rail offered alongside an uncapped method). Also set whenever the checkout offered exactly one category, since one option is already an answer.제공된 분류 중 이 결제가 사용할 분류입니다. OutlinePay가 고객에게 던진 질문에 고객이 답했을 때 설정되며, 이는 답이 수수료를 확정하는 체크아웃(상한 있는 은행 수단과 상한 없는 수단을 함께 제공)에서 일어납니다. 분류를 하나만 제공한 체크아웃에서도 설정됩니다. 선택지가 하나면 그 자체로 이미 답이기 때문입니다. Null only when several categories that price alike were offered. The customer still picks one, but they pick it on the processor's page after the price is settled, so there is nothing for us to record. Read `processor_payment_method` for what the processor actually used.가격이 같은 분류 여러 개를 제공했을 때만 null입니다. 고객은 여전히 하나를 고르지만, 가격이 확정된 뒤 처리사의 페이지에서 고르므로 기록할 것이 없습니다. 처리사가 실제로 사용한 수단은 `processor_payment_method`를 읽어 주십시오. nullable
One of다음 중 하나
|
card
|
object |
The card that settled this payment, as the processor read it off the card networks. It arrives with the other settlement facts, a moment after the outcome: null on the payment.succeeded event itself, filled on the payment.updated event that follows, exactly like fees.processor. Null forever on a payment no card settled, such as a bank rail or a payment that expired unpaid.이 결제를 정산한 카드 정보로, 처리사가 카드 네트워크에서 읽어 온 값입니다. 다른 정산 사실들과 함께 결과 직후에 도착합니다. payment.succeeded 이벤트 시점에는 아직 null이고, fees.processor와 똑같이 뒤따르는 payment.updated 이벤트에서 채워집니다. 은행 결제나 미결제 만료처럼 카드로 정산되지 않은 결제에서는 영구히 null입니다. A wallet payment is a card underneath, so it appears here too, with `wallet` naming which wallet presented it. A payment whose `processor_payment_method` reads "link" stays null, because the processor does not reveal the card behind its own wallet.간편결제도 내부적으로는 카드 결제이므로 여기에 함께 표시되며, 어느 지갑이 카드를 제시했는지는 `wallet`에 담깁니다. `processor_payment_method`가 "link"인 결제는 null로 유지됩니다. 처리사가 자사 지갑 뒤의 카드를 공개하지 않기 때문입니다. nullable |
card.brand
|
string |
The card's scheme, as the networks name it: "visa", "mastercard", "amex", "discover", "jcb", "unionpay" and more. A string rather than an enum of ours, so a new scheme appears the moment the processor reports one.카드 네트워크가 부르는 대로의 카드 브랜드입니다. "visa", "mastercard", "amex", "discover", "jcb", "unionpay" 등이 있습니다. OutlinePay의 enum이 아니라 문자열이므로, 처리사가 새 브랜드를 보고하는 즉시 그대로 나타납니다. nullable |
card.network
|
string |
The network the charge was actually routed over. Matches brand on almost every card. The two differ on a co-badged card, which carries two schemes and lets the processor pick the route.결제가 실제로 라우팅된 네트워크입니다. 거의 모든 카드에서 brand와 일치합니다. 두 브랜드를 함께 탑재해 처리사가 경로를 선택하는 겸용(co-badged) 카드에서만 달라집니다. nullable |
card.funding
|
string |
How the card draws money: "credit", "debit", "prepaid", or "unknown".카드의 자금 방식입니다. "credit", "debit", "prepaid", "unknown" 중 하나입니다. nullable |
card.last4
|
string |
The last four digits of the card number. The full number never reaches OutlinePay or you, so this is as much of it as ever exists on either side.카드 번호의 마지막 네 자리입니다. 전체 번호는 OutlinePay에도 파트너에게도 전달되지 않으므로, 양쪽 어디에도 이 이상은 존재하지 않습니다. nullable |
card.exp_month
|
integer |
Expiration month, 1 through 12.유효기간의 월로, 1부터 12까지입니다. nullable |
card.exp_year
|
integer |
Expiration year, four digits.유효기간의 연도로, 네 자리입니다. nullable |
card.country
|
string |
Two-letter ISO code of the country the card was issued in.카드 발급 국가의 두 글자 ISO 코드입니다. nullable |
card.authorization_code
|
string |
The approval number the issuer returned when it authorized the charge, the same code printed on a card receipt. Quote it when reconciling against card-company records. Null when the network did not return one.발급사가 결제를 승인하며 돌려준 승인번호로, 카드 매출전표에 인쇄되는 것과 같은 번호입니다. 카드사 기록과 대사할 때 이 번호를 사용하십시오. 네트워크가 승인번호를 돌려주지 않은 경우 null입니다. nullable |
card.wallet
|
string |
Set when a digital wallet presented the card: "apple_pay", "google_pay", and so on. Null on a plain card payment.간편결제 지갑이 카드를 제시한 경우에 설정됩니다. "apple_pay", "google_pay" 등입니다. 일반 카드 결제에서는 null입니다. nullable |
payment_link_id
|
string |
Set when the payment came from a link.링크에서 생성된 결제인 경우 설정됩니다. nullable |
checkout_url
|
string |
Hosted checkout URL. Present while the payment is not yet terminal, which includes `processing`: a delayed payment's page is where the customer sees what is still outstanding, and they may return to it days later. Null once the payment succeeds, fails or expires.호스팅 체크아웃 URL입니다. 결제가 종료 상태가 아닌 동안 존재하며, `processing`도 포함됩니다. 지연 결제의 페이지는 고객이 남은 절차를 확인하는 곳이라 며칠 뒤 다시 방문하기도 합니다. 결제가 성공, 실패 또는 만료되면 null이 됩니다. nullable |
receipt_url
|
string |
The customer-facing receipt: an OutlinePay-owned URL that resolves to the processor's hosted receipt, viewable in a browser and downloadable as a PDF. The document always shows the payment's latest state, refunds included. Appears when the payment succeeds, null before, and never expires. Share it with the customer or the merchant as proof of payment.고객용 영수증입니다. OutlinePay가 소유한 URL이며, 방문할 때마다 처리사의 호스팅 영수증으로 연결됩니다. 브라우저에서 조회하고 PDF로 저장할 수 있습니다. 영수증은 항상 결제의 최신 상태를 보여주며 환불 내역도 반영됩니다. 결제가 성공하면 나타나고 그 전에는 null이며, 만료되지 않습니다. 결제 증빙으로 고객이나 가맹점에 전달해 주십시오. nullable |
invoice_url
|
string |
The invoice, on a payment created with `invoice.enabled`: an OutlinePay-owned URL that resolves to the processor's hosted invoice, viewable in a browser and downloadable as a PDF. It is the merchant's own document, issued under their business details, and it shows the payment's latest state including refunds.`invoice.enabled`로 생성된 결제의 인보이스입니다. OutlinePay가 소유한 URL이며, 처리사의 호스팅 인보이스로 연결됩니다. 브라우저에서 조회하고 PDF로 저장할 수 있습니다. 가맹점 명의로 발행되는 가맹점 자신의 문서이며, 환불 내역을 포함해 결제의 최신 상태를 보여줍니다. Appears when the payment succeeds, null before, and null forever on a payment that did not ask for one. A receipt is not a substitute: `receipt_url` is proof that money moved, while this is the itemised document a buyer's accounting asks for. What it cost the merchant is `fees.invoice`.결제가 성공하면 나타나고 그 전에는 null이며, 인보이스를 요청하지 않은 결제에서는 계속 null입니다. 영수증으로 대신할 수 없습니다. `receipt_url`은 금액이 이동했다는 증빙이고, 이 문서는 구매자의 회계에서 요구하는 상세 문서입니다. 가맹점이 부담한 금액은 `fees.invoice`에 있습니다. nullable |
expires_at
|
string |
ISO 8601 UTC. When the *checkout session* lapses, not the payment. The window is set by the processor when the session is minted; for Stripe-hosted checkout that is 24 hours after creation. A payment still `awaiting_payment` at that moment expires.ISO 8601 UTC 형식입니다. 결제가 아니라 *체크아웃 세션*이 만료되는 시각입니다. 기간은 세션 발급 시 처리사가 정하며, Stripe 호스팅 체크아웃은 생성 후 24시간입니다. 이 시각까지 `awaiting_payment`인 결제는 만료됩니다. A payment in `processing` has already been paid for, so this is routinely in the past while the payment is perfectly healthy.`processing`인 결제는 이미 결제가 이루어진 것이므로, 결제가 멀쩡한데도 이 값이 과거인 경우가 흔합니다. nullable |
processing_at
|
string |
ISO 8601 UTC. When the customer finished and the payment entered processing. Only delayed methods reach this state.ISO 8601 UTC 형식입니다. 고객이 결제를 마치고 결제가 processing에 들어간 시각입니다. 지연 수단만 이 상태에 도달합니다. nullable |
succeeded_at
|
string |
nullable |
failed_at
|
string |
nullable |
expired_at
|
string |
nullable |
failure_reason
|
enum |
Why a payment failed, in OutlinePay's vocabulary, translated from the processor's own failure code at the boundary.결제가 실패한 이유로, 처리사의 실패 코드를 경계에서 OutlinePay의 용어로 변환한 값입니다. `insufficient_funds`: the account didn't have the money. Retry later, the account itself is fine.`insufficient_funds`: 계좌에 잔액이 없었습니다. 계좌 자체는 정상이므로 나중에 다시 시도하십시오. `account_closed`: the account no longer exists. Ask for different details.`account_closed`: 계좌가 더 이상 존재하지 않습니다. 다른 계좌 정보를 요청하십시오. `account_details_invalid`: the account or routing number was wrong, or a linked account's number was deactivated. Ask for correct details.`account_details_invalid`: 계좌 번호나 라우팅 번호가 잘못되었거나, 연동 계좌의 번호가 비활성화되었습니다. 올바른 정보를 요청하십시오. `not_authorized`: there's no valid authorization to debit this account, usually because the customer disputed an earlier debit. Collect a fresh authorization before trying again.`not_authorized`: 이 계좌를 출금할 유효한 승인이 없습니다. 대개 고객이 이전 출금에 이의를 제기한 경우입니다. 다시 시도하기 전에 새 승인을 받으십시오. `account_blocked`: the customer's bank is refusing debits, frozen or restricted. The customer has to sort it out with their bank.`account_blocked`: 고객의 은행이 출금을 거부하고 있습니다(동결 또는 제한). 고객이 은행과 직접 해결해야 합니다. `other`: the processor gave a reason we don't have a word for, or gave none. Treat it as a failure with no further guidance.`other`: 처리사가 대응하는 단어가 없는 이유를 제시했거나 이유를 제시하지 않았습니다. 추가 안내가 없는 실패로 처리하십시오. Why the payment failed, and null unless it did. Only bank rails reach it: a declined card doesn't end the checkout, the customer just tries again on the processor's page, so a card payment goes from `awaiting_payment` to `succeeded` or expires.결제가 실패한 이유이며, 실패하지 않았다면 null입니다. 은행 수단만 이 값에 도달합니다. 카드 거절은 체크아웃을 끝내지 않고 고객이 처리사 페이지에서 다시 시도하므로, 카드 결제는 `awaiting_payment`에서 `succeeded`로 가거나 만료됩니다. Grouped by what to do next rather than by the processor's own code. Several of Stripe's ACH codes call for the same action and fold into one value here.처리사의 코드가 아니라 다음에 할 일을 기준으로 묶었습니다. Stripe의 여러 ACH 코드가 같은 조치를 요구하므로 이곳에서는 하나의 값으로 접힙니다. nullable
One of다음 중 하나
|
payment_methods
|
array<string> |
The method categories you restricted this payment to, echoed back. Null means you did not ask, which offers the documented default of `["card", "wallet"]`, not every method the processor supports.이 결제를 제한하신 수단 분류를 그대로 반환합니다. null은 지정하지 않으셨다는 뜻이며, 이때 처리사가 지원하는 모든 수단이 아니라 문서화된 기본값 `["card", "wallet"]`이 제공됩니다. nullable |
bank_verification
|
enum |
How a customer's bank account must be proven to be theirs before it can be debited. Applies to `bank_debit` and is ignored on a checkout that offers no bank method.고객의 은행 계좌가 본인 것임을 어떻게 증명해야 출금할 수 있는지입니다. `bank_debit`에 적용되며, 은행 수단이 없는 체크아웃에서는 무시됩니다. `instant_or_delayed` (default): the customer links their bank instantly, or, if they'd rather not or their bank can't be reached, enters the account number and confirms two small deposits instead. That second path takes 1-2 business days for the deposits to arrive and gives them 10 days to enter them, so the payment can sit in `processing` for a fortnight. Accepts the most customers.`instant_or_delayed`(기본값): 고객이 은행을 즉시 연동하거나, 원치 않거나 연동되지 않는 은행이면 계좌 번호를 입력하고 소액 입금 2건을 확인합니다. 두 번째 경로는 입금 도착까지 영업일 1~2일이 걸리고 입력 기한이 10일이므로, 결제가 2주가량 `processing`에 머무를 수 있습니다. 가장 많은 고객을 수용합니다. `instant`: instant linking only. You learn within seconds whether the account is good, which is what you want if you ship on payment. The cost is real: a customer whose bank can't be reached this way can't pay by bank at all, so they either use another method or don't buy.`instant`: 즉시 연동만 허용합니다. 계좌가 유효한지 몇 초 안에 알 수 있으므로 결제 즉시 발송하신다면 이 방식이 맞습니다. 대가는 실질적입니다. 이 방식으로 연동되지 않는 은행의 고객은 은행 결제를 아예 사용할 수 없으므로, 다른 수단을 쓰거나 구매를 포기합니다. Echoed as you sent it. Null means you did not ask, so instant_or_delayed applied.보내신 그대로 반환합니다. null은 지정하지 않으셨다는 뜻이며, instant_or_delayed가 적용되었습니다. nullable
One of다음 중 하나
|
metadata
|
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
created_at
|
string |
ISO 8601 UTC.ISO 8601 UTC 형식입니다. |
{
"id": "pay_3Nk8Qh2Lmp7T",
"object": "payment",
"status": "awaiting_payment",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 10000,
"currency": "usd",
"description": "Order",
"customer": {
"email": "[email protected]"
},
"fees": {
"processor": null,
"outline": 50,
"partner": 100,
"dispute": 0,
"invoice": null,
"total": 150
},
"merchant_net": 9850,
"amount_refunded": 0,
"amount_refundable": 10000,
"refunds": [],
"disputes": [],
"processor": "stripe",
"processor_payment_method": null,
"selected_payment_method": null,
"card": null,
"bank_verification": null,
"payment_link_id": null,
"checkout_url": "https://checkout.outlinepay.com/c/pay_3Nk8Qh2Lmp7T",
"receipt_url": null,
"invoice_url": null,
"expires_at": "2026-07-22T12:45:00Z",
"processing_at": null,
"succeeded_at": null,
"failed_at": null,
"expired_at": null,
"failure_reason": null,
"created_at": "2026-07-21T12:45:00Z"
}
POST /v1/payments
Create a payment결제 생성
Creation is never a payment outcome. The response is status "awaiting_payment" plus an OutlinePay-owned checkout_url; whoever opens it completes the payment on the processor's hosted page. The terminal state (succeeded/failed/expired) arrives by webhook, with Retrieve a payment as the polling fallback. Point success_url and cancel_url at endpoints you control. The redirect is navigation, not proof of payment.결제 생성은 결제 결과가 아닙니다. 응답은 status가 "awaiting_payment"인 상태와 OutlinePay가 소유한 checkout_url이며, 이 주소를 여는 사람이 결제 처리사의 호스팅 페이지에서 결제를 완료합니다. 최종 상태(succeeded/failed/expired)는 웹훅으로 전달되고, 결제 조회가 폴링 대체 수단입니다. success_url과 cancel_url은 귀사가 관리하는 엔드포인트로 지정해 주십시오. 리디렉션은 화면 이동일 뿐 결제가 완료되었다는 증거가 아닙니다.
- Onboarding required온보딩 필수
- The merchant must have finished onboarding before you can charge it. Until the processor verifies the account this returns 409 merchant_not_onboarded and no payment is created. Put the merchant through Create an account session first; its status turns active and we emit merchant.updated when it can take money.결제를 요청하시려면 가맹점이 온보딩을 마쳐야 합니다. 결제 처리사가 계정을 검증하기 전까지는 409 merchant_not_onboarded가 반환되며 결제는 생성되지 않습니다. 먼저 계정 세션 생성으로 가맹점의 온보딩을 진행해 주십시오. 결제가 가능해지면 status가 active로 바뀌고 merchant.updated 이벤트를 발송합니다.
Conventions규약 Onboarding is required before charging결제 전 온보딩 필수·Payment methods결제 수단·Fees arrive just after the outcome수수료는 결과 직후에 도착합니다
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
merchant_id
required |
string |
|
amount
required |
integer |
Minor units of `currency` (for usd, cents). The minimum charge is 100 ($1.00): a lower amount is refused as a 400 invalid_request naming `amount`, before the processor is called.`currency`의 최소 단위 정수입니다(usd는 센트). 최소 결제 금액은 100($1.00)이며, 그보다 작은 금액은 처리사를 호출하기 전에 `amount`를 지목한 400 invalid_request로 거부됩니다. |
currency
optional |
enum |
What the customer is charged in (the presentment currency), as distinct from what the merchant is paid in. `usd` is the only value we accept today, and it is the default, so you can leave it out. Contact us if you need another.고객에게 청구되는 통화(표시 통화)이며, 가맹점이 지급받는 통화와 구분됩니다. 현재 허용되는 값은 `usd`뿐이고 기본값이므로 생략하셔도 됩니다. 다른 통화가 필요하시면 문의해 주십시오.
One of다음 중 하나
|
description
optional |
string |
|
customer
optional |
object |
Who is paying. Required (with `email`) whenever `payment_methods` includes `bank_transfer`; optional otherwise. The email keys the buyer's identity, so repeat buyers keep the same virtual account number.누가 결제하는지입니다. `payment_methods`에 `bank_transfer`가 포함될 때는 (`email`과 함께) 필수이고, 그 외에는 선택입니다. 이메일이 구매자의 식별자가 되므로, 같은 구매자는 결제할 때마다 같은 가상계좌 번호를 사용합니다. |
customer.email
optional |
string |
|
success_url
required |
string |
Where the processor sends the browser after payment.결제 후 처리사가 브라우저를 보내는 곳입니다. |
cancel_url
optional |
string |
Where the processor sends the browser on cancel.취소 시 처리사가 브라우저를 보내는 곳입니다. |
processor
optional |
string |
Which rail to charge on. Defaults to the merchant's default processor.결제에 사용할 경로입니다. 기본값은 가맹점의 기본 처리사입니다. |
payment_methods
optional |
array<string> |
Restrict the checkout to these method categories (an allow-list). Omit for the documented default, `["card", "wallet"]`. Naming `bank_transfer` requires `customer.email`.체크아웃을 이 수단 분류로 제한합니다(허용 목록). 생략하시면 문서화된 기본값 `["card", "wallet"]`이 적용됩니다. `bank_transfer`를 지정하려면 `customer.email`이 필요합니다. |
bank_verification
optional |
enum |
How a customer's bank account must be proven to be theirs before it can be debited. Applies to `bank_debit` and is ignored on a checkout that offers no bank method.고객의 은행 계좌가 본인 것임을 어떻게 증명해야 출금할 수 있는지입니다. `bank_debit`에 적용되며, 은행 수단이 없는 체크아웃에서는 무시됩니다. `instant_or_delayed` (default): the customer links their bank instantly, or, if they'd rather not or their bank can't be reached, enters the account number and confirms two small deposits instead. That second path takes 1-2 business days for the deposits to arrive and gives them 10 days to enter them, so the payment can sit in `processing` for a fortnight. Accepts the most customers.`instant_or_delayed`(기본값): 고객이 은행을 즉시 연동하거나, 원치 않거나 연동되지 않는 은행이면 계좌 번호를 입력하고 소액 입금 2건을 확인합니다. 두 번째 경로는 입금 도착까지 영업일 1~2일이 걸리고 입력 기한이 10일이므로, 결제가 2주가량 `processing`에 머무를 수 있습니다. 가장 많은 고객을 수용합니다. `instant`: instant linking only. You learn within seconds whether the account is good, which is what you want if you ship on payment. The cost is real: a customer whose bank can't be reached this way can't pay by bank at all, so they either use another method or don't buy.`instant`: 즉시 연동만 허용합니다. 계좌가 유효한지 몇 초 안에 알 수 있으므로 결제 즉시 발송하신다면 이 방식이 맞습니다. 대가는 실질적입니다. 이 방식으로 연동되지 않는 은행의 고객은 은행 결제를 아예 사용할 수 없으므로, 다른 수단을 쓰거나 구매를 포기합니다. Only meaningful when the checkout offers bank_debit. Omit it and you get instant_or_delayed.체크아웃이 bank_debit을 제공할 때만 의미가 있습니다. 생략하시면 instant_or_delayed가 적용됩니다.
One of다음 중 하나
|
invoice
optional |
object |
Ask the payment processor to issue an invoice once this payment succeeds. Off unless you send it, because the processor charges the merchant per invoice. It can only be decided here: the invoice's contents are fixed when the checkout is created and cannot be generated afterwards. The finished document is `invoice_url` on the payment, and what it cost the merchant is `fees.invoice`.결제가 성공하면 결제 처리사가 인보이스를 발행하도록 요청합니다. 보내지 않으면 꺼져 있습니다. 처리사가 인보이스 건당 가맹점에 수수료를 부과하기 때문입니다. 이 시점에만 결정할 수 있습니다. 인보이스의 내용은 체크아웃이 생성될 때 확정되며 이후에는 생성할 수 없습니다. 완성된 문서는 결제의 `invoice_url`에 있고, 가맹점이 부담한 금액은 `fees.invoice`에 있습니다. |
invoice.enabled
optional |
boolean |
Must be true or false. Anything else is refused rather than interpreted, so a stray value cannot bill the merchant for a document nobody asked for.true 또는 false여야 합니다. 그 외의 값은 해석하지 않고 거부합니다. 잘못 들어온 값 때문에 아무도 요청하지 않은 문서의 비용이 가맹점에 청구되지 않도록 하기 위해서입니다. |
metadata
optional |
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payments"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "merchant_id" => "mrc_9f2c8bAaZ1kQ", "amount" => 10000, "currency" => "usd", "description" => "Order", "customer" => [ "email" => "[email protected]", ], "success_url" => "https://pg.cookiepay.example/op/result", "cancel_url" => "https://pg.cookiepay.example/op/cancel", ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/payments" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "merchant_id": "mrc_9f2c8bAaZ1kQ", "amount": 10000, "currency": "usd", "description": "Order", "customer": { "email": "[email protected]" }, "success_url": "https://pg.cookiepay.example/op/result", "cancel_url": "https://pg.cookiepay.example/op/cancel" }'
Response응답
Returns a Payment.Payment 객체를 반환합니다.
{
"id": "pay_3Nk8Qh2Lmp7T",
"object": "payment",
"status": "awaiting_payment",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 10000,
"currency": "usd",
"description": "Order",
"customer": {
"email": "[email protected]"
},
"fees": {
"processor": null,
"outline": 50,
"partner": 100,
"dispute": 0,
"invoice": null,
"total": 150
},
"merchant_net": 9850,
"amount_refunded": 0,
"amount_refundable": 10000,
"refunds": [],
"disputes": [],
"processor": "stripe",
"processor_payment_method": null,
"selected_payment_method": null,
"card": null,
"bank_verification": null,
"payment_link_id": null,
"checkout_url": "https://checkout.outlinepay.com/c/pay_3Nk8Qh2Lmp7T",
"receipt_url": null,
"invoice_url": null,
"expires_at": "2026-07-22T12:45:00Z",
"processing_at": null,
"succeeded_at": null,
"failed_at": null,
"expired_at": null,
"failure_reason": null,
"created_at": "2026-07-21T12:45:00Z"
}
GET /v1/payments
List payments결제 목록 조회
Your payments, newest first. Filter by merchant_id and status.귀사의 결제를 최신순으로 반환합니다. merchant_id와 status로 필터링하실 수 있습니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
merchant_idoptional |
query |
string |
Only payments for this merchant.이 가맹점의 결제만 반환합니다. |
statusoptional |
query |
enum |
Only payments in this state.이 상태의 결제만 반환합니다. |
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payments?merchant_id=mrc_9f2c8bAaZ1kQ&limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/payments?merchant_id=mrc_9f2c8bAaZ1kQ&limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of Payment objects: { "data": [...], "has_more": bool }.Payment 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/payments/{id}
Retrieve a payment결제 조회
The authoritative status of a payment, the polling fallback to the webhook.결제의 기준 상태이며, 웹훅에 대한 폴링 대체 수단입니다.
Conventions규약 Fees arrive just after the outcome수수료는 결과 직후에 도착합니다·A dispute does not un-settle a payment분쟁은 결제 상태를 되돌리지 않습니다
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The payment id.결제 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payments/pay_3Nk8Qh2Lmp7T"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/payments/pay_3Nk8Qh2Lmp7T" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a Payment.Payment 객체를 반환합니다.
{
"id": "pay_3Nk8Qh2Lmp7T",
"object": "payment",
"status": "awaiting_payment",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 10000,
"currency": "usd",
"description": "Order",
"customer": {
"email": "[email protected]"
},
"fees": {
"processor": null,
"outline": 50,
"partner": 100,
"dispute": 0,
"invoice": null,
"total": 150
},
"merchant_net": 9850,
"amount_refunded": 0,
"amount_refundable": 10000,
"refunds": [],
"disputes": [],
"processor": "stripe",
"processor_payment_method": null,
"selected_payment_method": null,
"card": null,
"bank_verification": null,
"payment_link_id": null,
"checkout_url": "https://checkout.outlinepay.com/c/pay_3Nk8Qh2Lmp7T",
"receipt_url": null,
"invoice_url": null,
"expires_at": "2026-07-22T12:45:00Z",
"processing_at": null,
"succeeded_at": null,
"failed_at": null,
"expired_at": null,
"failure_reason": null,
"created_at": "2026-07-21T12:45:00Z"
}
Object객체
The PaymentLink objectPaymentLink 객체
Reusable, shareable URLs that mint a fresh checkout session on every visit.방문할 때마다 새 체크아웃 세션을 발급하는, 재사용과 공유가 가능한 URL입니다.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "payment_link".고정 문자열 "payment_link"입니다. |
url
|
string |
The permanent, OutlinePay-owned link URL.영구적인 OutlinePay 소유의 링크 URL입니다. |
status
|
enum |
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
merchant_id
|
string |
|
amount
|
integer |
|
currency
|
enum |
What the customer is charged in, fixed for the life of the link. `usd` is the only currency we support today.고객에게 청구되는 통화이며, 링크가 존재하는 동안 고정됩니다. 현재 지원 통화는 `usd`뿐입니다.
One of다음 중 하나
|
description
|
string |
nullable |
processor
|
string |
The rail this link charges on, e.g. "stripe". Fixed at creation; every session and payment it produces uses it.이 링크가 결제하는 경로입니다. 예: "stripe". 생성 시 고정되며, 링크가 만드는 모든 세션과 결제가 이 경로를 사용합니다. |
payment_methods
|
array<string> |
The method categories every session and payment this link mints is restricted to, echoed back. Fixed at creation, like the rail. Null means you did not ask, which offers the documented default of `["card", "wallet"]`.이 링크가 만드는 모든 세션과 결제가 제한되는 수단 분류를 그대로 반환합니다. 경로와 마찬가지로 생성 시 고정됩니다. null은 지정하지 않으셨다는 뜻이며, 문서화된 기본값 `["card", "wallet"]`이 제공됩니다. nullable |
bank_verification
|
enum |
How a customer's bank account must be proven to be theirs before it can be debited. Applies to `bank_debit` and is ignored on a checkout that offers no bank method.고객의 은행 계좌가 본인 것임을 어떻게 증명해야 출금할 수 있는지입니다. `bank_debit`에 적용되며, 은행 수단이 없는 체크아웃에서는 무시됩니다. `instant_or_delayed` (default): the customer links their bank instantly, or, if they'd rather not or their bank can't be reached, enters the account number and confirms two small deposits instead. That second path takes 1-2 business days for the deposits to arrive and gives them 10 days to enter them, so the payment can sit in `processing` for a fortnight. Accepts the most customers.`instant_or_delayed`(기본값): 고객이 은행을 즉시 연동하거나, 원치 않거나 연동되지 않는 은행이면 계좌 번호를 입력하고 소액 입금 2건을 확인합니다. 두 번째 경로는 입금 도착까지 영업일 1~2일이 걸리고 입력 기한이 10일이므로, 결제가 2주가량 `processing`에 머무를 수 있습니다. 가장 많은 고객을 수용합니다. `instant`: instant linking only. You learn within seconds whether the account is good, which is what you want if you ship on payment. The cost is real: a customer whose bank can't be reached this way can't pay by bank at all, so they either use another method or don't buy.`instant`: 즉시 연동만 허용합니다. 계좌가 유효한지 몇 초 안에 알 수 있으므로 결제 즉시 발송하신다면 이 방식이 맞습니다. 대가는 실질적입니다. 이 방식으로 연동되지 않는 은행의 고객은 은행 결제를 아예 사용할 수 없으므로, 다른 수단을 쓰거나 구매를 포기합니다. Echoed as you sent it, and applied to every session this link mints. Null means you did not ask, so instant_or_delayed applied.보내신 그대로 반환하며, 이 링크가 만드는 모든 세션에 적용됩니다. null은 지정하지 않으셨다는 뜻이며, instant_or_delayed가 적용되었습니다. nullable
One of다음 중 하나
|
invoice
|
object |
Whether every payment this link mints asks the processor for an invoice. Always present, `{"enabled": false}` when you did not ask, so off and never-asked read the same.이 링크로 생성되는 모든 결제가 처리사에 인보이스를 요청하는지 여부입니다. 항상 포함되며, 요청하지 않은 경우 `{"enabled": false}`입니다. 따라서 꺼진 것과 요청하지 않은 것이 같게 읽힙니다. |
invoice.enabled
|
boolean |
|
metadata
|
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
created_at
|
string |
{
"id": "link_7Hq2Rf9wKc1V",
"object": "payment_link",
"url": "https://buy.outlinepay.com/l/link_7Hq2Rf9wKc1V",
"status": "active",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 4900,
"currency": "usd",
"description": "Consulting session",
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/payment_links
Create a payment link결제 링크 생성
Returns a permanent OutlinePay-owned URL. No processor session is minted here. The first click does that. Each completed payment appears as its own payment object with its own webhook.OutlinePay가 소유한 영구 URL을 반환합니다. 이 시점에는 결제 처리사 세션이 생성되지 않고, 첫 클릭 시점에 생성됩니다. 완료된 결제는 각각 별도의 결제 객체로 생성되며 각자의 웹훅을 발생시킵니다.
- Onboarding required온보딩 필수
- A link is only worth handing out if the merchant behind it can be paid, so this is gated exactly like Create a payment: until the processor verifies the account it returns 409 merchant_not_onboarded and no link is created. Otherwise the first customer to click would be the one to discover the merchant isn't ready.링크는 그 뒤의 가맹점이 실제로 결제를 받을 수 있을 때에만 의미가 있으므로, 결제 생성과 동일하게 제한됩니다. 결제 처리사가 계정을 검증하기 전까지는 409 merchant_not_onboarded가 반환되며 링크는 생성되지 않습니다. 그렇지 않으면 링크를 처음 클릭한 고객이 가맹점의 미완료 상태를 대신 확인하게 됩니다.
Conventions규약 Onboarding is required before charging결제 전 온보딩 필수·Payment methods결제 수단
Emits이벤트 발행
payment_link.created
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
merchant_id
required |
string |
|
amount
required |
integer |
Minor units of `currency` (for usd, cents). Minimum 100 ($1.00), refused as a 400 invalid_request below it, as on Create a payment.`currency`의 최소 단위 정수입니다(usd는 센트). 최소 금액은 100($1.00)이며, 결제 생성과 마찬가지로 그보다 작으면 400 invalid_request로 거부됩니다. |
currency
optional |
enum |
What the customer is charged in (the presentment currency), fixed for the life of the link. `usd` is the only value we accept today, and it is the default.고객에게 청구되는 통화(표시 통화)이며, 링크가 존재하는 동안 고정됩니다. 현재 허용되는 값은 `usd`뿐이며 기본값입니다.
One of다음 중 하나
|
description
optional |
string |
|
processor
optional |
string |
Which rail this link charges on. Defaults to the merchant's default processor, and is fixed for the life of the link.이 링크가 결제하는 경로입니다. 기본값은 가맹점의 기본 처리사이며, 링크가 존재하는 동안 고정됩니다. |
payment_methods
optional |
array<string> |
Restrict every session and payment this link mints to these method categories (an allow-list), fixed for the life of the link. Omit for the documented default, `["card", "wallet"]`. `bank_transfer` is not accepted here: a virtual account number is issued to a known buyer, and a link has no buyer until someone opens it. Create payments instead.이 링크가 만드는 모든 세션과 결제를 이 수단 분류로 제한합니다(허용 목록). 링크가 존재하는 동안 고정됩니다. 생략하시면 문서화된 기본값 `["card", "wallet"]`이 적용됩니다. `bank_transfer`는 여기서 허용되지 않습니다. 가상계좌 번호는 특정 구매자에게 발급되는데, 링크는 누군가 열기 전까지 구매자가 없기 때문입니다. 대신 결제를 생성해 주십시오. |
bank_verification
optional |
enum |
How a customer's bank account must be proven to be theirs before it can be debited. Applies to `bank_debit` and is ignored on a checkout that offers no bank method.고객의 은행 계좌가 본인 것임을 어떻게 증명해야 출금할 수 있는지입니다. `bank_debit`에 적용되며, 은행 수단이 없는 체크아웃에서는 무시됩니다. `instant_or_delayed` (default): the customer links their bank instantly, or, if they'd rather not or their bank can't be reached, enters the account number and confirms two small deposits instead. That second path takes 1-2 business days for the deposits to arrive and gives them 10 days to enter them, so the payment can sit in `processing` for a fortnight. Accepts the most customers.`instant_or_delayed`(기본값): 고객이 은행을 즉시 연동하거나, 원치 않거나 연동되지 않는 은행이면 계좌 번호를 입력하고 소액 입금 2건을 확인합니다. 두 번째 경로는 입금 도착까지 영업일 1~2일이 걸리고 입력 기한이 10일이므로, 결제가 2주가량 `processing`에 머무를 수 있습니다. 가장 많은 고객을 수용합니다. `instant`: instant linking only. You learn within seconds whether the account is good, which is what you want if you ship on payment. The cost is real: a customer whose bank can't be reached this way can't pay by bank at all, so they either use another method or don't buy.`instant`: 즉시 연동만 허용합니다. 계좌가 유효한지 몇 초 안에 알 수 있으므로 결제 즉시 발송하신다면 이 방식이 맞습니다. 대가는 실질적입니다. 이 방식으로 연동되지 않는 은행의 고객은 은행 결제를 아예 사용할 수 없으므로, 다른 수단을 쓰거나 구매를 포기합니다. Only meaningful when the link offers bank_debit. Fixed for the life of the link. Omit it and you get instant_or_delayed.링크가 bank_debit을 제공할 때만 의미가 있습니다. 링크가 존재하는 동안 고정됩니다. 생략하시면 instant_or_delayed가 적용됩니다.
One of다음 중 하나
|
invoice
optional |
object |
Ask the payment processor to issue an invoice for every payment this link takes, once each one succeeds. The same option as on Create a payment, fixed for the life of the link like the rail and the methods. Off unless you send it, because the processor charges the merchant per invoice. Each payment the link mints then carries `invoice_url` and `fees.invoice`.이 링크로 받는 모든 결제에 대해, 각 결제가 성공하면 결제 처리사가 인보이스를 발행하도록 요청합니다. 결제 생성과 동일한 옵션이며, 결제 레일이나 결제 수단처럼 링크가 존재하는 동안 고정됩니다. 보내지 않으면 꺼져 있습니다. 처리사가 인보이스 건당 가맹점에 수수료를 부과하기 때문입니다. 이 링크로 생성된 각 결제에는 `invoice_url`과 `fees.invoice`가 포함됩니다. |
invoice.enabled
optional |
boolean |
Must be true or false. Anything else is refused rather than interpreted, so a stray value cannot bill the merchant for a document nobody asked for.true 또는 false여야 합니다. 그 외의 값은 해석하지 않고 거부합니다. 잘못 들어온 값 때문에 아무도 요청하지 않은 문서의 비용이 가맹점에 청구되지 않도록 하기 위해서입니다. |
metadata
optional |
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payment_links"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "merchant_id" => "mrc_9f2c8bAaZ1kQ", "amount" => 4900, "currency" => "usd", "description" => "Consulting session", ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/payment_links" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "merchant_id": "mrc_9f2c8bAaZ1kQ", "amount": 4900, "currency": "usd", "description": "Consulting session" }'
Response응답
Returns a PaymentLink.PaymentLink 객체를 반환합니다.
{
"id": "link_7Hq2Rf9wKc1V",
"object": "payment_link",
"url": "https://buy.outlinepay.com/l/link_7Hq2Rf9wKc1V",
"status": "active",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 4900,
"currency": "usd",
"description": "Consulting session",
"created_at": "2026-07-21T12:00:00Z"
}
GET /v1/payment_links
List payment links결제 링크 목록 조회
Your payment links, newest first. Filter by merchant_id.귀사의 결제 링크를 최신순으로 반환합니다. merchant_id로 필터링하실 수 있습니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
merchant_idoptional |
query |
string |
Only links for this merchant.이 가맹점의 링크만 반환합니다. |
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payment_links?merchant_id=mrc_9f2c8bAaZ1kQ&limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/payment_links?merchant_id=mrc_9f2c8bAaZ1kQ&limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of PaymentLink objects: { "data": [...], "has_more": bool }.PaymentLink 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/payment_links/{id}
Retrieve a payment link결제 링크 조회
The authoritative state of a link, including whether it is still active.활성 여부를 포함한 링크의 기준 상태입니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The payment link id.결제 링크 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payment_links/link_7Hq2Rf9wKc1V"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/payment_links/link_7Hq2Rf9wKc1V" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a PaymentLink.PaymentLink 객체를 반환합니다.
{
"id": "link_7Hq2Rf9wKc1V",
"object": "payment_link",
"url": "https://buy.outlinepay.com/l/link_7Hq2Rf9wKc1V",
"status": "active",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 4900,
"currency": "usd",
"description": "Consulting session",
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/payment_links/{id}/deactivate
Deactivate a payment link결제 링크 비활성화
Kills a link already in the wild. Later clicks get a clean "no longer active" page.이미 배포된 링크를 무효화합니다. 이후 클릭하면 "더 이상 사용할 수 없습니다" 안내 페이지가 표시됩니다.
Emits이벤트 발행
payment_link.deactivated
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The payment link id.결제 링크 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/payment_links/link_7Hq2Rf9wKc1V/deactivate"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/payment_links/link_7Hq2Rf9wKc1V/deactivate" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a PaymentLink.PaymentLink 객체를 반환합니다.
Object객체
The Refund objectRefund 객체
Return money for a succeeded payment, in full or in part.완료된(succeeded) 결제의 대금을 전액 또는 부분 반환합니다.
Refunds need no special test values: refund any succeeded test payment. For the one test-mode limitation (bank transfers), see Testing · Refunds.환불에는 별도의 테스트 값이 없으며, 성공한 테스트 결제를 환불하면 됩니다. 테스트 모드의 한 가지 제약(계좌 이체)은 테스트 · 환불 섹션을 참고해 주십시오.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "refund".고정 문자열 "refund"입니다. |
status
|
enum |
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
payment_id
|
string |
|
merchant_id
|
string |
|
processor
|
string |
The rail this refund settled on, e.g. "stripe". Inherited from the payment.이 환불이 정산된 경로입니다. 예: "stripe". 결제에서 물려받습니다. |
amount
|
integer |
|
metadata
|
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
created_at
|
string |
{
"id": "re_5Fp1Xy8nQd2W",
"object": "refund",
"status": "pending",
"mode": "test",
"payment_id": "pay_3Nk8Qh2Lmp7T",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 2500,
"created_at": "2026-07-21T12:10:00Z"
}
POST /v1/refunds
Create a refund환불 생성
Refunds a succeeded payment. Usually pending here and resolved by the refund.completed / refund.failed webhook. The platform fee is not returned.완료된(succeeded) 결제를 환불합니다. 보통 이 시점에는 처리 중 상태이며 refund.completed 또는 refund.failed 웹훅으로 확정됩니다. 플랫폼 수수료는 반환되지 않습니다.
- Amount is in the smallest currency unit금액은 해당 통화의 최소 단위입니다
- An integer, like every amount in this API: 2500 is $25.00 and 1 is one cent. Omit it to refund whatever is still owed, which is the payment's amount_refundable and not its amount. Several partial refunds are allowed as long as they add up to no more than that, so check amount_refundable rather than assuming a payment is still whole.이 API의 모든 금액과 마찬가지로 정수입니다. 2500은 25.00달러이고 1은 1센트입니다. 남은 금액을 모두 환불하시려면 생략하십시오. 기준은 결제의 amount가 아니라 amount_refundable입니다. 합계가 그 금액을 넘지 않는 한 부분 환불을 여러 번 하실 수 있으므로, 결제가 아직 전액 그대로라고 가정하지 마시고 amount_refundable을 확인해 주십시오.
- Only succeeded payments완료된 결제만 환불할 수 있습니다
- A payment that never succeeded has nothing to return, so this refuses with 400 invalid_request rather than creating a refund that could not settle. A fully refunded payment has amount_refundable 0 and refuses the same way.완료되지 않은 결제는 돌려줄 금액이 없으므로, 정산될 수 없는 환불을 생성하는 대신 400 invalid_request로 거부합니다. 이미 전액 환불된 결제는 amount_refundable이 0이며 동일하게 거부됩니다.
Conventions규약 A dispute does not un-settle a payment분쟁은 결제 상태를 되돌리지 않습니다
Emits이벤트 발행
refund.completed
Idempotency-Key
This endpoint requires an Idempotency-Key request header. A double-fired refund would move money twice.이 엔드포인트에는 Idempotency-Key 요청 헤더가 필수입니다. 환불이 중복 실행되면 자금이 두 번 이동하기 때문입니다.
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
payment_id
required |
string |
|
amount
optional |
integer |
Omit to refund what is still refundable.생략하시면 남은 환불 가능 금액이 모두 환불됩니다. |
metadata
optional |
object |
Your own key/value pairs, for correlating this object back to your records. We never interpret the contents: they are stored, returned on every read, carried on every event this object emits, and forwarded to the processor. At most 50 pairs; keys up to 40 characters, values up to 500. Values are stored as strings. Keys beginning outlinepay_, plus outline_fee and partner_fee, are reserved by OutlinePay and rejected. Because it reaches the processor, never put secrets here.이 객체를 귀사의 기록과 연결하기 위한 자체 키/값 쌍입니다. OutlinePay는 내용을 해석하지 않습니다. 저장되고, 모든 조회에 반환되며, 이 객체가 발행하는 모든 이벤트에 실리고, 결제 처리사에도 전달됩니다. 최대 50쌍, 키는 40자, 값은 500자까지이며 문자열로 저장됩니다. outlinepay_로 시작하는 키와 outline_fee, partner_fee는 OutlinePay가 예약하고 있어 거부됩니다. 처리사까지 전달되므로 비밀 정보는 절대 넣지 마십시오. |
Example request요청 예시
<?php // Mint once per refund, store it, resend the same value on every retry. $idempotencyKey = bin2hex(random_bytes(16)); $ch = curl_init("https://api.outlinepay.com/v1/refunds"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Idempotency-Key: " . $idempotencyKey, "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "payment_id" => "pay_3Nk8Qh2Lmp7T", "amount" => 2500, ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
# Mint once per refund, store it, resend the same value on every retry. curl -X POST "https://api.outlinepay.com/v1/refunds" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "payment_id": "pay_3Nk8Qh2Lmp7T", "amount": 2500 }'
Response응답
Returns a Refund.Refund 객체를 반환합니다.
{
"id": "re_5Fp1Xy8nQd2W",
"object": "refund",
"status": "pending",
"mode": "test",
"payment_id": "pay_3Nk8Qh2Lmp7T",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 2500,
"created_at": "2026-07-21T12:10:00Z"
}
GET /v1/refunds
List refunds환불 목록 조회
Your refunds across every payment, newest first. A payment already carries its own refunds inline, so reach for this when you do not have a payment in hand: reconciling a day's returns, or reporting over a window. Filter by payment_id to narrow it to one payment.모든 결제에 걸친 환불 내역이며 최신순입니다. 결제 객체에는 이미 해당 결제의 환불이 함께 담겨 있으므로, 이 엔드포인트는 결제 건을 특정하지 않은 경우에 사용하십시오. 하루치 환불을 대사하거나 특정 기간을 집계하실 때가 그렇습니다. payment_id로 특정 결제 한 건으로 좁히실 수 있습니다.
- Two views of the same refund같은 환불을 보는 두 가지 방식
- A payment's refunds[] array is the lean view (id, status, amount, metadata, created_at) because it is there to tell you what happened to that one payment. This endpoint returns the full Refund object, which additionally names its payment, merchant, mode and processor. The ids match, so either can be followed to the other.결제의 refunds[] 배열은 해당 결제에 무슨 일이 있었는지 알려 주기 위한 것이므로 간략형(id, status, amount, metadata, created_at)입니다. 이 엔드포인트는 전체 Refund 객체를 반환하며, 결제와 가맹점, 모드, 결제 처리사를 함께 담습니다. id가 서로 같으므로 어느 쪽에서든 다른 쪽으로 이동하실 수 있습니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
payment_idoptional |
query |
string |
Only refunds against this payment.이 결제에 대한 환불만 반환합니다. |
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/refunds?payment_id=pay_3Nk8Qh2Lmp7T&limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/refunds?payment_id=pay_3Nk8Qh2Lmp7T&limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of Refund objects: { "data": [...], "has_more": bool }.Refund 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/refunds/{id}
Retrieve a refund환불 조회
The authoritative state of a refund, the polling fallback to the webhook.환불의 기준 상태이며, 웹훅에 대한 폴링 대체 수단입니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The refund id.환불 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/refunds/re_5Fp1Xy8nQd2W"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/refunds/re_5Fp1Xy8nQd2W" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a Refund.Refund 객체를 반환합니다.
{
"id": "re_5Fp1Xy8nQd2W",
"object": "refund",
"status": "pending",
"mode": "test",
"payment_id": "pay_3Nk8Qh2Lmp7T",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 2500,
"created_at": "2026-07-21T12:10:00Z"
}
Object객체
The Dispute objectDispute 객체
Chargebacks a cardholder opened with their bank. Read-only; evidence is submitted by the merchant in the processor's embedded component.카드 소지자가 은행에 제기한 지불 거절입니다. 읽기 전용이며, 증빙은 가맹점이 결제 처리사의 임베드 컴포넌트에서 제출합니다.
Disputes can be rehearsed end to end in test mode, including winning and losing one. See Testing · Disputes.분쟁은 승소와 패소를 포함해 테스트 모드에서 끝까지 연습할 수 있습니다. 테스트 · 분쟁 섹션을 참고해 주십시오.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "dispute".고정 문자열 "dispute"입니다. |
status
|
enum |
The chargeback's state, in OutlinePay's vocabulary and translated from whichever processor reported it. The `inquiry_*` set is the card networks' early retrieval request, raised before a formal chargeback; the rest is the real lifecycle, terminating in `won`/`lost`, or `refunded` when the merchant refunds instead of contesting.지불 거절의 상태로, OutlinePay의 용어이며 어느 처리사가 보고했든 변환되어 있습니다. `inquiry_*` 계열은 정식 지불 거절 전에 제기되는 카드 네트워크의 사전 조회 요청이고, 나머지가 실제 라이프사이클입니다. `won`/`lost`로 끝나거나, 가맹점이 다투는 대신 환불하면 `refunded`가 됩니다.
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
payment_id
|
string |
|
merchant_id
|
string |
|
processor
|
string |
The rail the disputed charge is on, e.g. "stripe". Inherited from the payment.분쟁이 걸린 결제 건의 경로입니다. 예: "stripe". 결제에서 물려받습니다. |
reason
|
enum |
Why the cardholder disputed, in OutlinePay's vocabulary. Reason codes originate with the card networks but each processor normalises them differently, so we publish one set and fold theirs into it: bank_error covers the several ways a bank can decline to move the money, and anything we cannot place maps to other.카드 소지자가 지불 거절을 제기한 사유로, OutlinePay의 용어입니다. 사유 코드는 카드 네트워크에서 나오지만 처리사마다 다르게 정리하므로, 하나의 집합으로 공개하고 처리사의 값을 그 안으로 접습니다. bank_error는 은행이 자금 이동을 거절하는 여러 경우를 묶은 값이고, 분류할 수 없는 값은 other로 대응됩니다. nullable Accepted values (10)허용 값 (10개) |
amount
|
integer |
Disputed amount, minor units.분쟁 금액이며 최소 단위입니다. |
fee
|
integer |
What the processor charged the merchant to handle this dispute, in minor units (Stripe bills a flat 15.00 USD). Charged whether the dispute is won or lost, so winning still leaves the merchant down this much. The payment's fees.total and merchant_net account for it.이 분쟁의 처리 대가로 처리사가 가맹점에 청구한 금액이며 최소 단위입니다(Stripe는 정액 15.00 USD). 승패와 무관하게 청구되므로, 승소해도 가맹점은 이 금액만큼 손해입니다. 결제의 fees.total과 merchant_net에 반영됩니다. nullable |
amount_withheld
|
integer |
How much of the payment the processor is currently holding back over this dispute, in minor units. Equal to amount from the moment a dispute opens, and 0 once the merchant wins. While it is above zero the payment cannot be refunded.이 분쟁으로 처리사가 현재 보류 중인 결제 금액이며 최소 단위입니다. 분쟁이 열리는 순간부터 amount와 같고, 가맹점이 승소하면 0이 됩니다. 0보다 큰 동안에는 결제를 환불할 수 없습니다. nullable |
evidence_due_at
|
string |
Deadline to submit evidence, ISO 8601 UTC.증빙 제출 기한이며 ISO 8601 UTC 형식입니다. nullable |
created_at
|
string |
{
"id": "dp_7Hq2Rf9wKc1V",
"object": "dispute",
"status": "needs_response",
"mode": "test",
"payment_id": "pay_3Nk8Qh2Lmp7T",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"reason": "fraudulent",
"amount": 10000,
"fee": 1500,
"amount_withheld": 10000,
"evidence_due_at": "2026-08-04T23:59:59Z",
"created_at": "2026-07-21T13:00:00Z"
}
GET /v1/disputes
List disputes분쟁 목록 조회
Your disputes, newest first. Usually empty: a dispute exists only when a cardholder has opened a chargeback.귀사의 분쟁을 최신순으로 반환합니다. 카드 소지자가 지불 거절을 제기한 경우에만 분쟁이 존재하므로 보통은 비어 있습니다.
Conventions규약 A dispute does not un-settle a payment분쟁은 결제 상태를 되돌리지 않습니다
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/disputes?limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/disputes?limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of Dispute objects: { "data": [...], "has_more": bool }.Dispute 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/disputes/{id}
Retrieve a dispute분쟁 조회
A single dispute, including its evidence deadline. Read-only.증빙 제출 기한을 포함한 개별 분쟁입니다. 읽기 전용입니다.
Conventions규약 A dispute does not un-settle a payment분쟁은 결제 상태를 되돌리지 않습니다
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The dispute id.분쟁 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/disputes/dp_7Hq2Rf9wKc1V"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/disputes/dp_7Hq2Rf9wKc1V" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a Dispute.Dispute 객체를 반환합니다.
{
"id": "dp_7Hq2Rf9wKc1V",
"object": "dispute",
"status": "needs_response",
"mode": "test",
"payment_id": "pay_3Nk8Qh2Lmp7T",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"reason": "fraudulent",
"amount": 10000,
"fee": 1500,
"amount_withheld": 10000,
"evidence_due_at": "2026-08-04T23:59:59Z",
"created_at": "2026-07-21T13:00:00Z"
}
Object객체
The Event objectEvent 객체
The replayable log of everything OutlinePay has emitted for you.OutlinePay가 귀사에 발행한 모든 이벤트의 재생 가능한 기록입니다.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "event".고정 문자열 "event"입니다. |
type
|
enum |
The outbound event catalog.발신 이벤트 목록입니다. `payment.updated` is the only type that is not a change of state. It fires a moment after a payment's outcome, carrying the facts that can only be read off the charge: the processor's own fee, the method that settled, and the card behind a card payment. All are still null on the outcome event itself, so record net from `payment.updated`, not from `payment.succeeded`. The full rule is under "Fees arrive just after the outcome" in Conventions.`payment.updated`는 상태 변경이 아닌 유일한 타입입니다. 결제 결과 직후에 발송되며, 결제 건에서만 읽을 수 있는 사실들, 즉 처리사 자신의 수수료, 실제로 정산된 수단, 그리고 카드 결제의 경우 해당 카드 정보를 담습니다. 모두 결과 이벤트 시점에는 아직 null이므로, 순수령액은 `payment.succeeded`가 아니라 `payment.updated` 기준으로 기록하십시오. 전체 규칙은 Conventions의 "Fees arrive just after the outcome"에 있습니다. Accepted values (14)허용 값 (14개) |
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
created_at
|
string |
|
data
|
object |
The resource payload captured when the event was emitted: a Payment for payment.* events, a Merchant for merchant.*, and so on. Its `object` field names which, so a generic handler can branch on the payload rather than parsing the event type.이벤트 발행 시점에 캡처된 리소스 페이로드입니다. payment.* 이벤트에는 Payment가, merchant.*에는 Merchant가 담기는 식입니다. 어느 것인지는 페이로드의 `object` 필드가 알려 주므로, 범용 핸들러는 이벤트 타입 문자열을 파싱하는 대신 페이로드로 분기할 수 있습니다. |
{
"id": "evt_9sK4Tb3vLm8P",
"object": "event",
"type": "payment.succeeded",
"mode": "test",
"created_at": "2026-07-21T13:02:11Z",
"data": {
"id": "pay_3Nk8Qh2Lmp7T",
"object": "payment",
"status": "awaiting_payment",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 10000,
"currency": "usd",
"description": "Order",
"customer": {
"email": "[email protected]"
},
"fees": {
"processor": null,
"outline": 50,
"partner": 100,
"dispute": 0,
"invoice": null,
"total": 150
},
"merchant_net": 9850,
"amount_refunded": 0,
"amount_refundable": 10000,
"refunds": [],
"disputes": [],
"processor": "stripe",
"processor_payment_method": null,
"selected_payment_method": null,
"card": null,
"bank_verification": null,
"payment_link_id": null,
"checkout_url": "https://checkout.outlinepay.com/c/pay_3Nk8Qh2Lmp7T",
"receipt_url": null,
"invoice_url": null,
"expires_at": "2026-07-22T12:45:00Z",
"processing_at": null,
"succeeded_at": null,
"failed_at": null,
"expired_at": null,
"failure_reason": null,
"created_at": "2026-07-21T12:45:00Z"
}
}
GET /v1/events
List events이벤트 목록 조회
Everything OutlinePay has emitted for you, newest first. Replay past events any time. Filter by type.OutlinePay가 귀사에 발행한 모든 이벤트를 최신순으로 반환합니다. 지난 이벤트를 언제든 다시 받으실 수 있습니다. type으로 필터링하실 수 있습니다.
Conventions규약 Webhook delivery웹훅 전달
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
typeoptional |
query |
enum |
Only events of this type.이 타입의 이벤트만 반환합니다. |
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/events?limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/events?limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of Event objects: { "data": [...], "has_more": bool }.Event 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
GET /v1/events/{id}
Retrieve an event이벤트 조회
A single event exactly as it was emitted, for replaying or verifying a delivery.발행된 그대로의 개별 이벤트이며, 재처리하거나 전달 건을 검증하실 때 사용하십시오.
Conventions규약 Webhook delivery웹훅 전달
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The event id.이벤트 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/events/evt_9sK4Tb3vLm8P"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/events/evt_9sK4Tb3vLm8P" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a Event.Event 객체를 반환합니다.
{
"id": "evt_9sK4Tb3vLm8P",
"object": "event",
"type": "payment.succeeded",
"mode": "test",
"created_at": "2026-07-21T13:02:11Z",
"data": {
"id": "pay_3Nk8Qh2Lmp7T",
"object": "payment",
"status": "awaiting_payment",
"mode": "test",
"merchant_id": "mrc_9f2c8bAaZ1kQ",
"amount": 10000,
"currency": "usd",
"description": "Order",
"customer": {
"email": "[email protected]"
},
"fees": {
"processor": null,
"outline": 50,
"partner": 100,
"dispute": 0,
"invoice": null,
"total": 150
},
"merchant_net": 9850,
"amount_refunded": 0,
"amount_refundable": 10000,
"refunds": [],
"disputes": [],
"processor": "stripe",
"processor_payment_method": null,
"selected_payment_method": null,
"card": null,
"bank_verification": null,
"payment_link_id": null,
"checkout_url": "https://checkout.outlinepay.com/c/pay_3Nk8Qh2Lmp7T",
"receipt_url": null,
"invoice_url": null,
"expires_at": "2026-07-22T12:45:00Z",
"processing_at": null,
"succeeded_at": null,
"failed_at": null,
"expired_at": null,
"failure_reason": null,
"created_at": "2026-07-21T12:45:00Z"
}
}
Object객체
The WebhookEndpoint objectWebhookEndpoint 객체
Where OutlinePay delivers signed events. The signing secret is shown once, at creation.OutlinePay가 서명된 이벤트를 전달하는 곳입니다. 서명 시크릿은 생성 시 단 한 번만 표시됩니다.
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The literal string "webhook_endpoint".고정 문자열 "webhook_endpoint"입니다. |
url
|
string |
|
status
|
enum |
Always "active" today: a deleted endpoint leaves the API entirely rather than appearing as disabled.현재는 항상 "active"입니다. 삭제된 엔드포인트는 disabled로 표시되는 대신 API에서 완전히 사라집니다.
One of다음 중 하나
|
mode
|
enum |
The world this object lives in, test (sandbox) or live. Matches your API key's prefix (olp_sk_test_ / olp_sk_live_).이 객체가 속한 환경으로, test(샌드박스) 또는 live입니다. API 키의 접두사(olp_sk_test_ / olp_sk_live_)와 일치합니다.
One of다음 중 하나
|
secret
|
string |
Signing secret. Returned only on creation.서명 시크릿입니다. 생성 시에만 반환됩니다. nullable |
created_at
|
string |
{
"id": "we_2Bd7Nq4pRs9K",
"object": "webhook_endpoint",
"url": "https://pg.cookiepay.example/outlinepay/webhook",
"status": "active",
"mode": "test",
"secret": "olp_whsec_YOUR_SIGNING_SECRET",
"created_at": "2026-07-21T12:00:00Z"
}
POST /v1/webhook_endpoints
Create a webhook endpoint웹훅 엔드포인트 생성
Subscribes an HTTPS URL to your events. The response reveals the signing secret exactly once. Store it, and use it to verify the OutlinePay-Signature header on every delivery. Each mode allows up to 16 active endpoints; past that, creation fails with invalid_request until you delete one.HTTPS URL을 이벤트 수신 대상으로 등록합니다. 응답에는 서명 시크릿이 단 한 번만 포함되므로 반드시 저장하시고, 모든 전달 건의 OutlinePay-Signature 헤더 검증에 사용하십시오. 모드당 활성 엔드포인트는 최대 16개입니다. 초과하면 생성이 invalid_request로 거부되며, 기존 엔드포인트를 삭제하시면 다시 생성할 수 있습니다.
Conventions규약 Webhook delivery웹훅 전달
Request body요청 본문
| Field필드 | Type타입 | Description설명 |
|---|---|---|
url
required |
string |
An HTTPS URL to receive events.이벤트를 수신할 HTTPS URL입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/webhook_endpoints"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "url" => "https://pg.cookiepay.example/outlinepay/webhook", ]), ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X POST "https://api.outlinepay.com/v1/webhook_endpoints" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://pg.cookiepay.example/outlinepay/webhook" }'
Response응답
Returns a WebhookEndpoint.WebhookEndpoint 객체를 반환합니다.
{
"id": "we_2Bd7Nq4pRs9K",
"object": "webhook_endpoint",
"url": "https://pg.cookiepay.example/outlinepay/webhook",
"status": "active",
"mode": "test",
"secret": "olp_whsec_YOUR_SIGNING_SECRET",
"created_at": "2026-07-21T12:00:00Z"
}
GET /v1/webhook_endpoints
List webhook endpoints웹훅 엔드포인트 목록 조회
Your endpoints, newest first. The signing secret is never included here.귀사의 엔드포인트를 최신순으로 반환합니다. 서명 시크릿은 이곳에 포함되지 않습니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
limitoptional |
query |
integer |
Page size, 1–100 (default 20).페이지 크기이며 1~100(기본값 20)입니다. |
starting_afteroptional |
query |
string |
A resource id; returns records after it (newest-first cursor).리소스 id이며, 그 이후의 레코드를 반환합니다(최신순 커서). |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/webhook_endpoints?limit=20"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl "https://api.outlinepay.com/v1/webhook_endpoints?limit=20" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
Returns a page of WebhookEndpoint objects: { "data": [...], "has_more": bool }.WebhookEndpoint 객체의 목록 페이지를 반환합니다: { "data": [...], "has_more": bool }.
DELETE /v1/webhook_endpoints/{id}
Delete a webhook endpoint웹훅 엔드포인트 삭제
Deletes the endpoint. Deliveries stop immediately, it disappears from the list, its slot under the 16-endpoint cap frees up, and its id is gone: a repeat call answers 404. There is no undo; to start delivering to the same URL again, create a new endpoint (it will have a new signing secret).엔드포인트를 삭제합니다. 전달이 즉시 중단되고, 목록에서 사라지며, 16개 제한의 자리가 반환되고, 해당 id는 더 이상 유효하지 않습니다. 같은 id로 다시 호출하면 404로 응답합니다. 되돌릴 수 없습니다. 같은 URL로 다시 전달하시려면 새 엔드포인트를 생성해 주십시오. 새 서명 시크릿이 발급됩니다.
Parameters파라미터
| Parameter파라미터 | In위치 | Type타입 | Description설명 |
|---|---|---|---|
idrequired |
path |
string |
The webhook endpoint id.웹훅 엔드포인트 id입니다. |
Example request요청 예시
<?php $ch = curl_init("https://api.outlinepay.com/v1/webhook_endpoints/we_2Bd7Nq4pRs9K"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "DELETE", CURLOPT_HTTPHEADER => [ "Authorization: Bearer olp_sk_test_YOUR_KEY", ], ]); $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo $status . PHP_EOL; echo $response . PHP_EOL;
curl -X DELETE "https://api.outlinepay.com/v1/webhook_endpoints/we_2Bd7Nq4pRs9K" \ -H "Authorization: Bearer olp_sk_test_YOUR_KEY"
Response응답
| Field필드 | Type타입 | Description설명 |
|---|---|---|
id
|
string |
|
object
|
string |
The type of the resource that was deleted.삭제된 리소스의 타입입니다. |
deleted
|
boolean |
Always true.항상 true입니다. |
{
"id": "we_2Bd7Nq4pRs9K",
"object": "webhook_endpoint",
"deleted": true
}