diff --git a/src/router/index.js b/src/router/index.js
index 5ecdb1aa6810c7537a332b086903c8f27e412d8f..5829299ef8df2b987ba2e634334520b7e90f226a 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -58,6 +58,11 @@ const routes = [
     name: 'VoucherList',
     component: () => import('@/views/VoucherList.vue'),
   },
+  {
+    path: '/voucher/create',
+    name: 'VoucherCreate',
+    component: () => import('@/views/VoucherCreate.vue'),
+  },
   {
     path: '/voucher/:id',
     name: 'VoucherDetail',
diff --git a/src/views/VoucherCreate.vue b/src/views/VoucherCreate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..86187dff3fd61cec216cce7e3cf041f81d7d79db
--- /dev/null
+++ b/src/views/VoucherCreate.vue
@@ -0,0 +1,109 @@
+<template>
+  <div class="voucher-create">
+    <v-card
+      :loading="isProcessing"
+    >
+      <v-card-title>프로그램 등록</v-card-title>
+      <v-card-text>
+        <v-alert
+          v-if="error.isError"
+          dense
+          text
+          type="error"
+        >
+          {{ error.message }}
+        </v-alert>
+        <program-field
+          :program.sync="voucher.program"
+        ></program-field>
+        <v-text-field
+          label="이용횟수"
+          v-model="voucher.quantity"
+        ></v-text-field>
+      </v-card-text>
+      <v-card-actions>
+        <v-spacer></v-spacer>
+        <v-btn
+          color="error"
+          outlined
+          @click="cancel"
+        >
+          <v-icon
+            left
+          >
+            mdi-delete
+          </v-icon>
+          취소
+        </v-btn>
+        <v-btn
+          color="primary"
+          outlined
+          @click="createVoucher"
+        >
+          <v-icon
+            left
+          >
+            mdi-content-save
+          </v-icon>
+          저장
+        </v-btn>
+      </v-card-actions>
+    </v-card>
+  </div>
+</template>
+
+<script>
+import APISetting from '@/settings/api';
+import ProgramField from '@/components/ProgramField.vue';
+
+export default {
+  name: 'VoucherCreate',
+
+  components: {
+    ProgramField,
+  },
+
+  data: () => ({
+    isProcessing: false,
+    error: {
+      isError: false,
+      message: '',
+    },
+    voucher: {
+      program: {
+        title: '',
+      },
+      quantity: '',
+    },
+  }),
+
+  methods: {
+    createVoucher() {
+      this.error.isError = false;
+      this.error.message = '';
+      this.isProcessing = true;
+
+      fetch(APISetting.endpoints.voucher.list, APISetting.settings.post(this.voucher))
+        .then((res) => {
+          if ([201, 400, 500].includes(res.status)) return Promise.all([res.json(), res]);
+          throw new Error('알 수 없는 응답입니다.');
+        })
+        .then((values) => {
+          const [json, res] = values;
+          if (res.status !== 201) throw new Error(json.message);
+          this.$router.push('/voucher');
+        })
+        .catch((e) => {
+          this.error.message = e.message;
+          this.error.isError = true;
+        })
+        .finally(() => {
+          this.isProcessing = false;
+        });
+    },
+    cancel() {
+      this.$router.push('/voucher');
+    },
+  },
+};
+</script>