LogoLogo
  • 🧩i'mport Payment Integration Docs
    • 🚗GET STARTED
  • 🛫Setup
    • 🖥️1. Create an account
    • 🧷2. Set up PG
      • 🏢Payment gateway settings
        • ⌨️NHN KCP
        • ⌨️KG INICIS
        • ⌨️NICE Payments
        • ⌨️Toss Payments
        • ⌨️KICC
        • ⌨️Paymentwall
        • ⌨️Daou
        • ⌨️다날 설정
        • ⌨️JTNET 설정
        • ⌨️세틀뱅크 설정
        • ⌨️KG모빌리언스 설정
        • ⌨️스마트로 설정
        • ⌨️페이팔 설정
        • ⌨️엑심베이 설정
        • ⌨️블루월넛 설정
      • ⛺간편 결제사
        • ⌨️카카오페이 설정
        • ⌨️토스간편결제 설정
        • ⌨️네이버페이(결제형) 설정
        • ⌨️페이코 설정
        • ⌨️차이 설정
        • ⌨️알리페이 설정
    • ✔️3. Check required info
  • Payment window
    • 🖥️Authenticated payment
      • 📒Definition
      • 🌠1. Add i'mport library
      • 💡2. Initialize IMP object
      • 🪧3. Request payment
      • 🎁4. Process payment result
        • 🪟Iframe method
        • 🖼️Redirect method
      • 🔦5. Verify payment information
      • 🛬6. Complete payment
    • ⏰Non-authenticated payment
      • 🏍️Request billing key payment
        • 🖱️REST API
        • 🛡️PG window
      • 💳Key-in payment using card info
      • 🪧Subscription payment using billing key
    • 💸Payment cancellation (refund)
      • 💷Virtual account refund
  • Payment result
    • ⚒️Set up a webhook
  • Other Services
    • 📱Mobile identity verification
      • 📔1. Prepare for verification
      • 🥏2. Request verification
      • 🚚3. Send verification result
      • 🤹4. Get verification info
    • 🚚Integrated identity verification
      • 📒Prepare for verification
      • 🥏Request verification
      • 🚚Send verification result
      • 🤹Get verification info
    • 💳Credit card identity verification
      • 📒1. Prepare for verification
      • 🥏2. Request verification
      • 🚚3. Send verification result
      • 🤹4. Get verification info
    • 💻Generate payment URL
    • 🛩️Integrate budget handler
    • 📟Native mobile SDKs
  • TIPS
    • 🌽Tax exemption on payments
    • ✅Service launch checklist
    • 🔏Confirm Process
    • 🎼i'mport payment flow
    • 🎈Agency & Tier
    • 📦Billing key issuance by PG
    • 🏦Bank codes by PG
    • 🧾PG codes
    • 🚚Courier codes
    • 🪧What is redirection?
    • 📰PG error codes
  • Admin console
    • 🎡Admin console guide
      • Apply for online payment
      • My ID & API keys
      • Manage admin & sub-merchant accounts
      • Integrate payment
      • Payment activity
    • 💻Integrating Multiple PGs
  • API
    • 📋i'mport API overview
    • 🖇️REST API Access Token
    • 💳Payment API
      • ⌨️Cancel payment API
      • ⌨️Get payment API
      • ⌨️Get payments API
      • ⌨️Get payments by status API
      • ⌨️Get payments by order ID, status (All)
      • ⌨️Get payments by order ID, status (Top 1)
      • ⌨️Get balance API (for split payment transaction)
      • ⌨️Get payments by billing key API
      • ⌨️Save payment amount API
      • ⌨️Update payment amount API
      • ⌨️Get payment amount API
    • 📝Billing key API
      • ⌨️Request billing key API
      • ⌨️Delete billing key API
      • ⌨️Get billing key API
      • ⌨️Get billing keys API
      • ⌨️Get scheduled payments API
    • 🧭Subscription payment API
      • ⌨️Schedule payment API
      • ⌨️Cancel scheduled payment API
      • ⌨️Get scheduled payments API
      • ⌨️Get scheduled payment API
      • ⌨️Get scheduled payments by billing key API
    • 🪂Non-authenticated payment API
      • ⌨️Request non-authenticated payment (billing key) API
      • ⌨️Request non-authenticated payment (one-time) API
    • 🇺🇲🇺🇲 Overseas PG API
      • ⌨️Paymentwall delivery API
    • 👮‍♂️👮♂ Identity verification API
      • ⌨️Get identity verification result API
      • ⌨️Delete identity verification API
      • ⌨️Request identity verification API
      • ⌨️Confirm identity verification API
    • 🎫Simple payment service API
      • 🧽Kakao Pay
        • ⌨️Get order API
      • 🛩️KCP Quick Pay
        • ⌨️Delete user API
      • 🧰PAYCO
        • ⌨️Update order status API
      • 📗Naver Pay
        • ⌨️Confirm escrow order API
        • ⌨️Accrue points API
        • ⌨️Get cash receipt amount API
    • 🏦Escrow API
      • ⌨️Get delivery info API
      • ⌨️Add delivery info API
      • ⌨️Update delivery info API
    • 💵Cash receipt API
      • ⌨️Cancel cash receipt transaction API
      • ⌨️Get cash receipt API
      • ⌨️Request cash receipt API
      • ⌨️Cancel cash receipt (external) API
      • ⌨️Get cash receipt (external) API
      • ⌨️Request cash receipt (external) API
    • 🏛️Virtual account API
      • ⌨️Request virtual account API
      • ⌨️Cancel virtual account API
      • ⌨️Update virtual account API
      • ⌨️Get account holder API
    • 🍶Miscellaneous API
      • 🎽Benepia point
        • ⌨️Get points API
        • ⌨️Request point payment API
      • 🏪Convenience store payment
        • ⌨️Request barcode API
        • ⌨️Cancel barcode API
      • 🗃️Financial institution codes
        • ⌨️Get credit card codes (All) API
        • ⌨️Get credit card name API
        • ⌨️Get bank codes (All) API
        • ⌨️Get bank name API
      • 🛖PG information
        • ⌨️Get PG MIDs API
  • SDK
    • 📚Javascript SDK
      • 💿Payment request parameters
      • 📀Payment response parameters
      • 💿Identity verification request parameters
      • 📀Identity verification response parameters
      • ✏️SDK Release Notes
  • FAQ
    • ⁉️FAQ
  • 🔑Payment integration by PG
    • 🏢Payment gateways
      • ⌨️NHH KCP
      • ⌨️KG INICIS
      • ⌨️Toss Payments
      • ⌨️NICE Payments
      • ⌨️KICC
      • ⌨️Daou (PAYJOA)
        • 📍Precautions for using PAYJOA
      • ⌨️KG Mobilians
      • ⌨️Paymentwall
      • ⌨️Danal
      • ⌨️Settlebank
      • ⌨️JTNET
      • ⌨️Smartro
      • ⌨️PayPal
      • ⌨️Eximbay
      • ⌨️Blue Walnut
    • ⛺Simple payments
      • ⌨️Naver Pay (Standard)
      • ⌨️Kakao Pay
      • ⌨️PAYCO
      • ⌨️Alipay
      • ⌨️Toss
  • Korean Integration Docs
Powered by GitBook
On this page
  • STEP 01. Request cancellation
  • STEP 02. Get payment information
  • STEP 03. Request refund to i'mport server
  • STEP 04. Save refund result
  • STEP 04. Handle response for refund request
  1. Payment window

Payment cancellation (refund)

Learn how to cancel a payment using the i'mport payment cancel API.

STEP 01. Request cancellation

Request a refund to the server with the required refund information. In the case of virtual account refund, you need to specify additional parameters for the refund deposit account information. The following example requests a refund with the required refund information.

client-side
<button onclick="cancelPay()">Request Refund</button>
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script><!-- jQuery CDN --->
<script>
  function cancelPay() {
    jQuery.ajax({
      "url": "{URL to receive refund request}", // Example: http://www.myservice.com/payments/cancel
      "type": "POST",
      "contentType": "application/json",
      "data": JSON.stringify({
        "merchant_uid": "{Order ID}", // Example: ORD20180131-0000011
            "cancel_request_amount": 2000, // Refund amount
            "reason": "Testing payment refund" // Reason for the refund
            "refund_holder": "Jone Doe", // [required for virtual account refund] refund account holder's name
            "refund_bank": "88" // [required for virtual account refund] refund account bank code (e.g. Shinhan Bank is 88 for KG Inicis)
            "refund_account": "56211105948400" // [required for virtual account refund] refund account number
      }),
      "dataType": "json"
    });
  }
</script>

client-side
class CancelPay extends React.Component {
  cancelPay = () => {
    axios({
      url: "{URL to receive refund request}", // Example: http://www.myservice.com/payments/cancel
      method: "POST",
      headers: {
        "Content-Type": "application/json,
      },
      data: { 
        merchant_uid: "mid_" + new Date().getTime(), // Order ID
        cancel_request_amount: 2000, // Refund amount
        reason: "Refund for test payment" // Reason for the refund
        refund_holder: "Jone Doe", // [required for virtual account refund] refund account holder's name
        refund_bank: "88" // [required for virtual account refund] refund account bank code (e.g. Shinhan Bank is 88 for KG Inicis)
        refund_account: "56211105948400" // [required for virtual account refund] refund account number
      }
    });
  }
  ...
  render() {
    return <button onClick={this.cancelPay}>Request Refund</button>;
  }
}

STEP 02. Get payment information

Assume that there is a Payments table that stores payment information as follows:

server-side
/* ... model/payments.js ... */
  var mongoose = require('mongoose');
  var Schema = mongoose.Schema;
  ...
  var PaymentsSchema = new Schema({
    imp_uid: String, // i'mport unique ID (unique key for refund)
    merchant_uid: String, // order ID (used to query payment information)
    amount: { type: Number, default: 0 }, // Payment amount (for calculating refundable amount)
    cancel_amount: { type: Number, default: 0 }, // Total amount refunded (for calculating refundable amount)
    ...
  });
  ...
  module.exports = mongoose.model('Payments', PaymentsSchema);

Query the payment information of the order from the Payments table using the order ID (merchant_uid) received from the client.

server-side
  /* ... Omitted ... */
  var Payments = require('./models/payments');
  app.post('/payments/cancel', async (req, res, next) => {
    try {
      /* Get access token */
      /* ... Omitted ... */
      /* Get payment information */
      const { body } = req;
      const { merchant_uid } = body; // Order ID from the client
      Payments.find({ merchant_uid }, async function(err, payment) { 
        if (err) {
          return res.json(err);
        }
        const paymentData = payment[0]; // Save payment information
        /* Call i'mport REST API to request refund */
        ...
      });
    } catch (error) {
      res.status(400).send(error);
    }
  });

STEP 03. Request refund to i'mport server

Note - Refunding mobile micropayments

  • If a refund is requested on a different month from when the payment is made, a full refund is not allowed. For example, a payment made on January 31st is not refundable on February 1st.

Setting parameters for refund request:

Refund unique key

Set imp_uid or merchant_uid as the unique key that identifies the transaction to be refunded. The value of imp_uid takes precedence, and if an invalid imp_uid value is entered, the refund request will fail regardless of the merchant_uid value.

Refund amount (amount)

Enter the refund amount. If amount is not specified, the full amount will be refunded.

Refundable amount (checksum)

Enter the refundable amount. For example, the checksum of a product that costs 10,000 won is 10,000. If this payment has been partially refunded for 1,000 won in the past, the checksum is 9000 for the subsequent refund request. The checksum is used to check whether the refundable amount is the same between the merchant server and the i'mport server. If they do not match, the refund request will fail. If the checksum is not specified, the verification is not performed.

Reason for entering checksum

checksum is not required, but it is recommended for comparing the refundable amount between the merchant server and the i'mport server.

For example, consider the case when a partial refund request of 1,000 won for a 10,000 won payment was completed on the i'mport server, but not on the merchant server due to a server or database error. In this case, the checksum of the i'mport server is changed to 9000, but that of the merchant server remains 10,000.

If you attempt to make a refund request with checksum(10000), the request will fail because the value does not match the checksum(9000) of the i'mport server.

The following example requests a refund.

Node.js
  /* ... Omitted ... */
  app.post('/payments/cancel', async (req, res, next) => {
    try {
      /* Get access token */
      /* ... Omitted ... */
      /* Get payment information */
      const { body } = req;
      const { merchant_uid, reason, cancel_request_amount } = body; // Order ID from the client, reason for refund, refund amount
      Payments.find({ merchant_uid }, async function(err, payment) { 
        /* ... Omitted ... */
        const paymentData = payment[0]; // Save payment information
        const { imp_uid, amount, cancel_amount } = paymentData; // Get imp_uid, amount(paid amount), cancel_amount(total refund amount) from payment information
        const cancelableAmount = amount - cancel_amount; // Refundable amount (= paid amount - total refund amount)
        if (cancelableAmount <= 0) { // If refundable amount is 0
          return res.status(400).json({ message: "This order has already been fully refunded." });
        }
        ...
        /* Call i'mport REST API to request refund */
        const getCancelData = await axios({
          url: "{URL to receive refund request}", // Example: http://www.myservice.com/payments/cancel
          method: "post",
          headers: {
            "Content-Type": "application/json",
            "Authorization": access_token // Access token from i'mport server
          },
          data: {
            reason, // Reason for refund from client
            imp_uid, // Unique key for refund
            amount: cancel_request_amount, // Requested refund amount
            checksum: cancelableAmount // [Recommended] refundable amount
          }
        });
        const { response } = getCancelData.data; // Refund result
        /* Save refund result */
        ...
      });
    } catch (error) {
      res.status(400).send(error);
    }
  });

STEP 04. Save refund result

After the refund process is completed, save the result in the database as follows:

Node.js
  /* ... Omitted ... */
  app.post('/payments/cancel', async (req, res, next) => {
    try {
      /* Get access token */
      /* ... Omitted ... */
      /* Get payment information */
      Payments.find({ merchant_uid }, async function(err, payment) { 
        /* ... Omitted ... */
        /* Call i'mport REST API to request refund */
        /* ... Omitted ... */
        const { response } = getCancelData.data; // Refund result
        /* Save refund result */
        const { merchant_uid } = response; // Get order info from refund response
        Payments.findOneAndUpdate({ merchant_uid }, response, { new: true }, function(err, payment) { // Get and update payment information for the order
          if (err) {
            return res.json(err);
          }
          res.json(payment); // Return refund result to the client
        });
      });
    } catch (error) {
      res.status(400).send(error);
    }
  });

Note - When cancelling a payment

STEP 04. Handle response for refund request

Add the client-side logic to handle the response from the server as follows:

client-side
<button onclick="cancelPay()">Request Refund</button>
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script><!-- jQuery CDN --->
<script>
  function cancelPay() {
    jQuery.ajax({
      /* ... Omitted ... */
    }).done(function(result) { // If refund is successful 
      alert("Refund successful");
    }).fail(function(error) { // If refund fails
      alert("Refund failed");
    });
  }
</script>
client-side
class CancelPay extends React.Component {
  cancelPay = () => {
    axios({
      /* ... Omitted ... */
    }).then(response => { // If refund is successful 
      alert("Refund successful");
    }).catch(error => { // If refund fails 
      alert("Refund failed");
    });
  }
  ...
  render() {
    return <button onClick={this.cancelPay}>Request Refund</button>;
  }
}
PreviousSubscription payment using billing keyNextVirtual account refund

Last updated 2 years ago

To request a refund, you must first get a . Use the access token to call the to request a refund.

Even if a response code of 200 (OK) is returned for the REST API () request, a non-zero code in the response body means that the refund has failed. You can check the reason for the failure in the message of the body.

💸
REST API access token
i'mport cancel API
POST https://api.iamport.kr/payments/cancel
Sample refund button