diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeService.kt
index a8756b5..25cb5ca 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeService.kt
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
 import kr.co.bootpay.Bootpay
 import kr.co.vividnext.sodalive.can.CanRepository
 import kr.co.vividnext.sodalive.can.charge.event.ChargeSpringEvent
+import kr.co.vividnext.sodalive.can.coupon.CanCouponNumberRepository
 import kr.co.vividnext.sodalive.can.payment.Payment
 import kr.co.vividnext.sodalive.can.payment.PaymentGateway
 import kr.co.vividnext.sodalive.can.payment.PaymentStatus
@@ -29,6 +30,8 @@ class ChargeService(
     private val chargeRepository: ChargeRepository,
     private val canRepository: CanRepository,
     private val memberRepository: MemberRepository,
+    private val couponNumberRepository: CanCouponNumberRepository,
+
     private val objectMapper: ObjectMapper,
     private val okHttpClient: OkHttpClient,
     private val applicationEventPublisher: ApplicationEventPublisher,
@@ -43,6 +46,31 @@ class ChargeService(
     private val appleInAppVerifyUrl: String
 ) {
 
+    @Transactional
+    fun chargeByCoupon(couponNumber: String, member: Member) {
+        val canCouponNumber = couponNumberRepository.findByCouponNumber(couponNumber = couponNumber)
+            ?: throw SodaException("잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.")
+
+        if (canCouponNumber.member != null) {
+            throw SodaException("이미 사용한 쿠폰번호 입니다.")
+        }
+
+        val coupon = canCouponNumber.canCoupon!!
+        val couponCharge = Charge(0, coupon.can, status = ChargeStatus.COUPON)
+        couponCharge.title = "${coupon.can} 캔"
+        couponCharge.member = member
+
+        val payment = Payment(
+            status = PaymentStatus.COMPLETE,
+            paymentGateway = PaymentGateway.PG
+        )
+        payment.method = coupon.couponName
+        couponCharge.payment = payment
+        chargeRepository.save(couponCharge)
+
+        member.charge(0, coupon.can, "pg")
+    }
+
     @Transactional
     fun charge(member: Member, request: ChargeRequest): ChargeResponse {
         val can = canRepository.findByIdOrNull(request.canId)
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeStatus.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeStatus.kt
index 1585dcd..c31a16d 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeStatus.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/ChargeStatus.kt
@@ -1,7 +1,7 @@
 package kr.co.vividnext.sodalive.can.charge
 
 enum class ChargeStatus {
-    CHARGE, REFUND_CHARGE, EVENT, CANCEL,
+    CHARGE, REFUND_CHARGE, EVENT, COUPON, CANCEL,
 
     // 관리자 지급
     ADMIN,
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponController.kt
index c67c4f7..5962f3a 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponController.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponController.kt
@@ -89,4 +89,19 @@ class CanCouponController(private val service: CanCouponService) {
             )
             .body(InputStreamResource(response))
     }
+
+    @PostMapping("/use")
+    fun useCanCoupon(
+        @RequestBody request: UseCanCouponRequest,
+        @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
+    ) = run {
+        if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
+
+        ApiResponse.ok(
+            service.useCanCoupon(
+                couponNumber = request.couponNumber,
+                memberId = member.id!!
+            )
+        )
+    }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponIssueService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponIssueService.kt
new file mode 100644
index 0000000..547e7fa
--- /dev/null
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponIssueService.kt
@@ -0,0 +1,31 @@
+package kr.co.vividnext.sodalive.can.coupon
+
+import kr.co.vividnext.sodalive.common.SodaException
+import org.springframework.stereotype.Service
+
+@Service
+class CanCouponIssueService(private val couponNumberRepository: CanCouponNumberRepository) {
+    fun validateAvailableUseCoupon(couponNumber: String, memberId: Long) {
+        val canCouponNumber = checkCanCouponNumber(couponNumber)
+
+        if (!isMultipleUse(canCouponNumber)) {
+            val canCouponNumberList = couponNumberRepository.findByMemberId(memberId = memberId)
+            if (canCouponNumberList.isNotEmpty()) {
+                throw SodaException("해당 쿠폰은 1회만 충전이 가능합니다.")
+            }
+        }
+    }
+
+    private fun checkCanCouponNumber(couponNumber: String): CanCouponNumber {
+        val canCouponNumber = couponNumberRepository.findByCouponNumber(couponNumber = couponNumber)
+            ?: throw SodaException("잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.")
+
+        if (canCouponNumber.member != null) {
+            throw SodaException("이미 사용한 쿠폰번호 입니다.")
+        }
+
+        return canCouponNumber
+    }
+
+    private fun isMultipleUse(canCouponNumber: CanCouponNumber) = canCouponNumber.canCoupon!!.isMultipleUse
+}
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponNumberRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponNumberRepository.kt
index c51c98c..0e4ccd1 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponNumberRepository.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponNumberRepository.kt
@@ -14,6 +14,10 @@ interface CanCouponNumberQueryRepository {
     fun getCouponNumberList(couponId: Long, offset: Long, limit: Long): List<GetCouponNumberListItemResponse>
 
     fun getAllCouponNumberList(couponId: Long): List<GetCouponNumberListItemResponse>
+
+    fun findByCouponNumber(couponNumber: String): CanCouponNumber?
+
+    fun findByMemberId(memberId: Long): List<Long>
 }
 
 class CanCouponNumberQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : CanCouponNumberQueryRepository {
@@ -66,4 +70,19 @@ class CanCouponNumberQueryRepositoryImpl(private val queryFactory: JPAQueryFacto
             .orderBy(canCouponNumber.id.asc())
             .fetch()
     }
+
+    override fun findByCouponNumber(couponNumber: String): CanCouponNumber? {
+        return queryFactory
+            .selectFrom(canCouponNumber)
+            .where(canCouponNumber.couponNumber.eq(couponNumber))
+            .fetchFirst()
+    }
+
+    override fun findByMemberId(memberId: Long): List<Long> {
+        return queryFactory
+            .select(canCouponNumber.id)
+            .from(canCouponNumber)
+            .where(canCouponNumber.member.id.eq(memberId))
+            .fetch()
+    }
 }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponService.kt
index e5b95bc..f0474b8 100644
--- a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponService.kt
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/CanCouponService.kt
@@ -3,9 +3,12 @@ package kr.co.vividnext.sodalive.can.coupon
 import com.fasterxml.jackson.databind.ObjectMapper
 import kr.co.vividnext.sodalive.aws.sqs.SqsEvent
 import kr.co.vividnext.sodalive.aws.sqs.SqsEventType
+import kr.co.vividnext.sodalive.can.charge.ChargeService
 import kr.co.vividnext.sodalive.common.SodaException
+import kr.co.vividnext.sodalive.member.MemberRepository
 import org.apache.poi.xssf.usermodel.XSSFWorkbook
 import org.springframework.context.ApplicationEventPublisher
+import org.springframework.data.repository.findByIdOrNull
 import org.springframework.stereotype.Service
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
@@ -14,9 +17,14 @@ import java.time.format.DateTimeFormatter
 
 @Service
 class CanCouponService(
+    private val issueService: CanCouponIssueService,
+    private val chargeService: ChargeService,
+
     private val repository: CanCouponRepository,
     private val couponNumberRepository: CanCouponNumberRepository,
 
+    private val memberRepository: MemberRepository,
+
     private val objectMapper: ObjectMapper,
     private val applicationEventPublisher: ApplicationEventPublisher
 ) {
@@ -91,6 +99,17 @@ class CanCouponService(
         }
     }
 
+    fun useCanCoupon(couponNumber: String, memberId: Long) {
+        val member = memberRepository.findByIdOrNull(id = memberId)
+            ?: throw SodaException("로그인 정보를 확인해주세요.")
+
+        if (member.auth == null) throw SodaException("쿠폰은 본인인증을 하셔야 사용이 가능합니다.")
+
+        issueService.validateAvailableUseCoupon(couponNumber, memberId)
+
+        chargeService.chargeByCoupon(couponNumber, member)
+    }
+
     private fun insertHyphens(input: String): String {
         return input.chunked(4).joinToString("-")
     }
diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/UseCanCouponRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/UseCanCouponRequest.kt
new file mode 100644
index 0000000..b0083ea
--- /dev/null
+++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/coupon/UseCanCouponRequest.kt
@@ -0,0 +1,3 @@
+package kr.co.vividnext.sodalive.can.coupon
+
+data class UseCanCouponRequest(val couponNumber: String)