프로모션 결제 연동하기

프로모션 할인금액을 적용하는 방법을 안내합니다.

프로모션 결제 연동하기

고객사에서 카드사 즉시할인을 쉽게 적용하고 운영 관리하실 수 있도록 프로모션 기능을 제공하고 있습니다. 포트원 콘솔 내 프로모션 메뉴에서 카드사 별 프로모션을 생성 후 결제 요청 시 적용할 수 있으며, 프로모션에 설정된 예산, 할인방식, 할인금액/할인률에 따라 자동으로 계산되어 결제가 승인됩니다.

프로모션 메뉴의 경우 도입 고객사에 한하여 포트원 콘솔 내에서 확인하실 수 있습니다.

프로모션 결제를 연동하시려면 관리자콘솔에서 프로모션을 먼서 생성해야합니다. 프로모션 생성 방법이 궁금하다면 프로모션 설정 가이드를 확인해 보세요.

프로모션 할인 금액 표시하기

포트원에서 제공하는 프로모션을 이용하시는 경우 결제 요청 전 고객사에서 주문 페이지를 구현하여 사용하시길 권장드립니다.

고객사의 주문 페이지에 프로모션 할인 금액을 표시하시려면 프로모션 단건 조회 API를 참고하여 사용할 프로모션 아이디로 API를 조회한 후 응답 필드의 discountPolicy.partitions[] 내의 schemeamountFrom 데이터를 갖고 직접 계산해서 사용하시길 권장드립니다.

프로모션 할인 정책 조회 예시

예를 들어 조회할 프로모션의 할인 정책이 10000원 이상 결제 시 10% 할인, 50000원 이상 결제 시 20% 할인 이라면 discountPolicy 필드는 아래와 같이 조회가 될 것입니다.

const promotion = {
  // ... other fields
  discountPolicy: {
    partitions: [
      {
        amountFrom: 10000,
        scheme: {
          type: "PERCENT",
          percent: 10,
        },
      },
      {
        amountFrom: 50000,
        scheme: {
          type: "PERCENT",
          percent: 20,
        },
      },
    ],
  },
};

아래와 같은 로직으로 프로모션이 적용된 이후의 금액을 계산하실 수 있습니다.

const selectDiscountScheme = (partitions, amount) => {
  const select = (partitions) => {
    const [head, ...tail] = partitions;
    if (tail.length === 0) {
      return head.scheme;
    }

    const from = head.amountFrom;
    const to = tail[0].amountFrom;

    if (from <= amount && amount < to) return head.scheme;
    else return select(tail);
  };

  if (partitions[0].amountFrom > amount) return null;
  else return select(partitions);
};

const getPaymentAmount = (discountScheme, amount) => {
  if (discountScheme.type == "PERCENT") {
    // 정률 할인
    return amount - (amount * discountScheme.percent) / 100;
  } else {
    // 정액 할인
    return amount - discountScheme.amount;
  }
};

const orderAmount = getOrderAmount();
const response = await fetch(
  `https://api.portone.io/promotions/${promotionId}`,
  {
    method: "GET",
    headers: {
      Authorization: `PortOne ${PORTONE_API_SECRET}`,
      "Content-Type": "application/json",
    },
  },
);
const promotion = await response.json();

// 금액 구간에 맞는 할인 정책을 구합니다.
const discountScheme = selectDiscountScheme(
  promotion.discountPolicy.partitions,
  orderAmount,
);
// 프로모션이 적용된 실결제 금액을 구합니다.
const paymentAmount = getPaymentAmount(discountScheme, orderAmount);

SDK(결제창) 인증결제 연동하기

SDK를 이용하는 경우 결제 호출 시 생성한 프로모션의 ID를 전용 파라미터인 promotionId에 지정하여 사용이 가능합니다.

프로모션 결제의 경우 특정 카드사 결제 시 적용되므로 결제 호출 시 카드 다이렉트호출 방식만 지원되며, 해당 프로모션의 카드사와 다이렉트 호출 카드사가 일치하는 경우에만 프로모션 조건이 적용됩니다.

만약, 카드사가 일치하지 않는 경우 에러가 리턴되며 결제 진행이 불가하오니 유의하시길 바랍니다.

이 외에 다른 결제 기능들은 기존과 동일하게 사용이 가능합니다.

인증결제와 관련된 자세한 내용은 인증결제 연동하기결제요청 파라미터 문서를 참고하시기 바랍니다.

예제 코드

//포트원 인증결제 SDK 호출
PortOne.requestPayment({
  storeId: "store-4ff4af41-85e3-4559-8eb8-0d08a2c6ceec",
  promotionId: "promotion-id-86e1ff2a-2c3a-451c-bdd3-e5cd1664bc3e", //적용할 프로모션 아이디 입력 (Ex. 현대카드 프로모션)
  //카드 다이렉트 호출
  card: {
    cardCompany: "HYUNDAI_CARD",
  },
  //기타 인증결제 파라미터 설정
  channelKey: "channel-key-f042e8e2-92f1-4f68-ad61-cec6ede41529",
  paymentId: `payment-${crypto.randomUUID()}`,
  orderName: "나이키 와플 트레이너 2 SD",
  totalAmount: 1000,
  currency: "CURRENCY_KRW",
  payMethod: "CARD",
  customer: {
    fullName: "홍길동",
    phoneNumber: "010-1234-5678",
    email: "test@test.com",
  },
});

주요 파라미터

promotionId string

프로모션 ID

  • 관리자 콘솔의 [프모로션] 메뉴에서 확인할 수 있습니다.

  • 프로모션 ID 지정 및 카드 다이렉트 방식으로 결제창을 호출하면, 프로모션 내 설정된 할인 조건 및 금액에 따라 할인 금액이 적용되어 결제가 진행됩니다.

card object

카드 정보

  • cardCompany string

카드사 다이렉트 호출 시 필요한 카드사 식별 값

카드 다이렉트 호출 시 카드사 식별 값 문서를 참조하여 프로모션과 동일한 카드사로 지정해야 합니다.

유의사항

API 수기(키인)결제 연동하기

API를 이용하는 경우 결제 호출 시 생성한 프로모션의 ID를 전용 파라미터인 promotionId에 지정하여 사용이 가능합니다.

해당 프로모션의 카드사와 수기(키인) 결제 요청 시 입력한 카드의 카드사가 일치하는 경우에만 프로모션 조건이 적용됩니다. (입력한 카드의 카드사 정보는 카드 BIN번호를 기준으로 체크됩니다.) 만약, 카드사가 일치하지 않는 경우 에러가 리턴되며 결제 진행이 불가하오니 유의하시길 바랍니다.

이 외에 다른 결제 기능들은 기존과 동일하게 사용이 가능합니다.

수기(키인)결제와 관련된 자세한 내용은 수기(키인)결제 연동하기 문서를 참고하시기 바랍니다.

예제 코드

// 포트원 수기(키인)결제 API 호출
const paymentResponse = await fetch(
  `https://api.portone.io/payments/${encodeURIComponent(UNIQUE_PAYMENT_ID)}/instant`,
  {
    method: "POST",
    headers: {
      Authorization: `PortOne ${PORTONE_API_SECRET}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      channelKey: "channel-key-f042e8e2-92f1-4f68-ad61-cec6ede41529",
      //적용할 프로모션 아이디 입력
      promotionId: "promotion-id-86e1ff2a-2c3a-451c-bdd3-e5cd1664bc3e",
      orderName: "1개월 이용권",
      // 수기 결제 API를 참고해 고객 정보를 채워주세요.
      customer: {
        name: {
          full: "김포트", // 고객 이름을 입력해야 합니다.
        },
      },
      amount: {
        total: 8900,
      },
      currency: "KRW",

      // 수기(키인)결제 API를 참고해 카드 정보를 채워주세요.
      method: {
        card: {
          cardCredintial: {
            number: "0000123400001234", // 16자리 숫자만 입력해야 합니다.
            expiryYear: "26", // 연도의 뒤 2자리를 입력해야 합니다.
            expiryMonth: "12",
            birthOrBusinessRegistrationNumber: "900101", // 생년월일 6자리 또는 사업자 등록번호 10자리를 입력해야 합니다.
            passwordTwoDigits: "00", // 카드 비밀번호 앞 2자리 입력해야 합니다.
          },
        },
      },
    }),
  },
);
if (!paymentResponse.ok)
  throw new Error(`paymentResponse: ${await paymentResponse.json()}`);

주요 파라미터

promotionId * string

프로모션 ID

  • 관리자 콘솔의 [프모로션] 메뉴에서 확인할 수 있습니다.

  • 프로모션 ID 지정 및 카드 다이렉트 방식으로 결제창을 호출하면, 프로모션 내 설정된 할인 조건 및 금액에 따라 할인 금액이 적용되어 결제가 진행됩니다.

유의사항

API 정기결제 연동하기

발급된 빌링키를 이용하여 단건 결제 API 또는 예약 결제 API를 이용하는 경우 API 요청시 생성한 프로모션의 ID를 전용 파라미터인 promotionId에 지정하여 사용이 가능합니다.

해당 프로모션의 카드사와 발급된 빌링키의 카드사가 일치하는 경우에만 프로모션 조건이 적용됩니다. 만약, 카드사가 일치하지 않는 경우 에러가 리턴되며 결제 진행이 불가하오니 유의하시길 바랍니다.

예약 결제를 사용하시는 경우 결제가 실행되는 시점에 예약 시 입력한 프로모션 아이디를 기반으로 예산 및 조건을 확인한 후 적용됩니다. 만약 결제가 실행되는 시점에 예산 소진 상태이거나 프로모션이 종료된 상태인 경우 할인이 적용되지 않습니다.

이 외에 다른 결제 기능들은 기존과 동일하게 사용이 가능합니다.

빌링키 결제와 관련된 자세한 내용은 빌링결제 연동하기 문서를 참고하시기 바랍니다.

예제 코드

const issueResponse = await fetch(
  `https://api.portone.io/payments/${encodeURIComponent(UNIQUE_PAYMENT_ID)}/billing-key`,
  {
    method: "POST",
    headers: {
      Authorization: `PortOne ${PORTONE_API_SECRET}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      billingKey: "billing-key-018fa367-cdd9-d8fd-2256-c43ce0e475d6", // 발급된 빌링키 값을 입력해야 합니다.
      promotionId: "promotion-id-86e1ff2a-2c3a-451c-bdd3-e5cd1664bc3e", //적용할 프로모션 아이디 입력
      orderName: "후불 결제",
      customer: {
        id: "customerId_2333", // 고객사가 지정한 고객 식별정보를 입력해야 합니다.
        name: {
          full: "김포트", // 고객 이름을 입력해야 합니다.
        },
        phoneNumber: "01000001234", // 고객 전화번호를 입력해야 합니다.
        email: "port@portone.io", // 고객 이메일을 입력해야 합니다.
      },
      amount: {
        total: 8900,
      },
      currency: "KRW",
    }),
  },
);
if (!issueResponse.ok)
  throw new Error(`issueResponse: ${await issueResponse.json()}`);
const issueResponse = await fetch(
  `https://api.portone.io/payments/${encodeURIComponent(UNIQUE_PAYMENT_ID)}/schedule`,
  {
    method: "POST",
    headers: {
      Authorization: `PortOne ${PORTONE_API_SECRET}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      payment: {
        billingKey: "billing-key-018fa367-cdd9-d8fd-2256-c43ce0e475d6", // 발급된 빌링키 값을 입력해야 합니다.
        promotionId: "promotion-id-86e1ff2a-2c3a-451c-bdd3-e5cd1664bc3e", //적용할 프로모션 아이디 입력
        orderName: "월간 이용권 정기 결제",
        customer: {
          id: "customerId_2333", // 고객사가 지정한 고객 식별정보를 입력해야 합니다.
          name: {
            full: "김포트", // 고객 이름을 입력해야 합니다.
          },
          phoneNumber: "01000001234", // 고객 전화번호를 입력해야 합니다.
          email: "port@portone.io", // 고객 이메일을 입력해야 합니다.
        },
        amount: {
          total: 8900,
        },
        currency: "KRW",
      },
      timeToPay: "2024-05-01T00:00:00+09:00", // ISO8601 형식으로 입력해야 합니다.
    }),
  },
);
if (!issueResponse.ok)
  throw new Error(`issueResponse: ${await issueResponse.json()}`);

주요 파라미터

promotionId * string

프로모션 ID

  • 관리자 콘솔의 [프모로션] 메뉴에서 확인할 수 있습니다.

  • 프로모션 ID 지정 및 카드 다이렉트 방식으로 결제창을 호출하면, 프로모션 내 설정된 할인 조건 및 금액에 따라 할인 금액이 적용되어 결제가 진행됩니다.

유의사항

공통 유의사항

프로모션 서비스에서 제공하는 로직은 내부 사정에 의해 변동될 수 있으며, 변동 시 고객사에 사전 고지될 예정입니다.