콘텐츠 상세, 콘텐츠 구매
- pg 테스트 계정의 경우 캔이 아닌 원으로 표시되도록 하고 콘텐츠 구매시 바로 결제 후 구매 되도록 수정
This commit is contained in:
		| @@ -127,4 +127,6 @@ enum AppStep { | ||||
|     case seriesAll(creatorId: Int) | ||||
|      | ||||
|     case seriesContentAll(seriesId: Int, seriesTitle: String) | ||||
|          | ||||
|     case tempCanPayment(title: String, can: Int, onSuccess: () -> Void) | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,7 @@ struct ContentDetailCreatorProfileView: View { | ||||
|              | ||||
|             Text(creator.nickname) | ||||
|                 .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                 .foregroundColor(Color(hex: "777777")) | ||||
|                 .foregroundColor(Color.gray77) | ||||
|                 .padding(.horizontal, 5.3) | ||||
|              | ||||
|             Spacer() | ||||
|   | ||||
| @@ -14,16 +14,18 @@ struct ContentDetailPurchaseButton: View { | ||||
|      | ||||
|     var body: some View { | ||||
|         HStack(spacing: 0) { | ||||
|             Image("ic_can") | ||||
|                 .resizable() | ||||
|                 .frame(width: 16.7, height: 16.7) | ||||
|             if UserDefaults.int(forKey: .userId) != 17958 { | ||||
|                 Image("ic_can") | ||||
|                     .resizable() | ||||
|                     .frame(width: 16.7, height: 16.7) | ||||
|             } | ||||
|              | ||||
|             Text("\(price)") | ||||
|             Text(UserDefaults.int(forKey: .userId) == 17958 ? "\(price * 110)" : "\(price)") | ||||
|                 .font(.custom(Font.bold.rawValue, size: 14.7)) | ||||
|                 .foregroundColor(.white) | ||||
|                 .padding(.leading, 5.3) | ||||
|              | ||||
|             Text("캔으로") | ||||
|             Text(UserDefaults.int(forKey: .userId) == 17958 ? "원으로": "캔으로") | ||||
|                 .font(.custom(Font.light.rawValue, size: 12)) | ||||
|                 .foregroundColor(.white) | ||||
|              | ||||
|   | ||||
| @@ -38,7 +38,7 @@ struct ContentDetailView: View { | ||||
|                              | ||||
|                             Text("콘텐츠 상세") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                                 .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                         } | ||||
|                          | ||||
|                         Spacer() | ||||
| @@ -99,7 +99,7 @@ struct ContentDetailView: View { | ||||
|                                                 .foregroundColor(.white) | ||||
|                                                 .frame(maxWidth: .infinity) | ||||
|                                                 .frame(height: 48.7) | ||||
|                                                 .background(Color(hex: "525252")) | ||||
|                                                 .background(Color.gray52) | ||||
|                                                 .cornerRadius(5.3) | ||||
|                                                 .padding(.top, 18.3) | ||||
|                                                 .padding(.horizontal, 13.3) | ||||
| @@ -113,7 +113,7 @@ struct ContentDetailView: View { | ||||
|                                                     .foregroundColor(.white) | ||||
|                                                     .frame(maxWidth: .infinity) | ||||
|                                                     .frame(height: 48.7) | ||||
|                                                     .background(Color(hex: "525252")) | ||||
|                                                     .background(Color.gray52) | ||||
|                                                     .cornerRadius(5.3) | ||||
|                                                     .padding(.top, 18.3) | ||||
|                                                     .padding(.horizontal, 13.3) | ||||
| @@ -162,7 +162,7 @@ struct ContentDetailView: View { | ||||
|                                         .padding(.horizontal, 13.3) | ||||
|                                          | ||||
|                                         Rectangle() | ||||
|                                             .foregroundColor(Color(hex: "232323")) | ||||
|                                             .foregroundColor(Color.gray23) | ||||
|                                             .frame(height: 6.7) | ||||
|                                             .padding(.top, 24) | ||||
|                                          | ||||
| @@ -207,7 +207,7 @@ struct ContentDetailView: View { | ||||
|                          | ||||
|                         if proxy.safeAreaInsets.bottom > 0 { | ||||
|                             Rectangle() | ||||
|                                 .foregroundColor(Color(hex: "222222")) | ||||
|                                 .foregroundColor(Color.gray22) | ||||
|                                 .frame(width: proxy.size.width, height: 15.3) | ||||
|                         } | ||||
|                     } | ||||
| @@ -226,7 +226,20 @@ struct ContentDetailView: View { | ||||
|                             orderType: orderType, | ||||
|                             isOnlyRental: audioContent.isOnlyRental, | ||||
|                             onClickConfirm: { | ||||
|                                 viewModel.order(orderType: orderType) | ||||
|                                 if UserDefaults.int(forKey: .userId) == 17958 { | ||||
|                                     AppState.shared | ||||
|                                         .setAppStep( | ||||
|                                             step: .tempCanPayment( | ||||
|                                                 title: audioContent.title, | ||||
|                                                 can: orderType == .RENTAL ? Int(ceil(Double(audioContent.price) * 0.6)) : audioContent.price, | ||||
|                                                 onSuccess: { | ||||
|                                                     viewModel.order(orderType: orderType) | ||||
|                                                 } | ||||
|                                             ) | ||||
|                                         ) | ||||
|                                 } else { | ||||
|                                     viewModel.order(orderType: orderType) | ||||
|                                 } | ||||
|                             } | ||||
|                         ) | ||||
|                     } | ||||
| @@ -272,7 +285,7 @@ struct ContentDetailView: View { | ||||
|                              | ||||
|                             if proxy.safeAreaInsets.bottom > 0 { | ||||
|                                 Rectangle() | ||||
|                                     .foregroundColor(Color(hex: "222222")) | ||||
|                                     .foregroundColor(Color.gray22) | ||||
|                                     .frame(width: proxy.size.width, height: 15.3) | ||||
|                             } | ||||
|                         } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ struct ContentOrderConfirmDialogView: View { | ||||
|             VStack(spacing: 0) { | ||||
|                 Text("구매확인") | ||||
|                     .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                     .foregroundColor(Color.grayee) | ||||
|                  | ||||
|                 HStack(spacing: 11) { | ||||
|                     ZStack(alignment: .topLeading) { | ||||
| @@ -48,7 +48,7 @@ struct ContentOrderConfirmDialogView: View { | ||||
|                          | ||||
|                         Text(audioContent.title) | ||||
|                             .font(.custom(Font.bold.rawValue, size: 11.3)) | ||||
|                             .foregroundColor(Color(hex: "d2d2d2")) | ||||
|                             .foregroundColor(Color.grayd2) | ||||
|                             .padding(.top, 2) | ||||
|                          | ||||
|                         HStack(spacing: 4.3) { | ||||
| @@ -60,13 +60,13 @@ struct ContentOrderConfirmDialogView: View { | ||||
|                              | ||||
|                             Text(audioContent.creator.nickname) | ||||
|                                 .font(.custom(Font.medium.rawValue, size: 10)) | ||||
|                                 .foregroundColor(Color(hex: "777777")) | ||||
|                                 .foregroundColor(Color.gray77) | ||||
|                         } | ||||
|                         .padding(.top, 6.7) | ||||
|                          | ||||
|                         Text(audioContent.duration) | ||||
|                             .font(.custom(Font.medium.rawValue, size: 11)) | ||||
|                             .foregroundColor(Color(hex: "777777")) | ||||
|                             .foregroundColor(Color.gray77) | ||||
|                             .padding(.top, 6.7) | ||||
|                     } | ||||
|                      | ||||
| @@ -77,52 +77,74 @@ struct ContentOrderConfirmDialogView: View { | ||||
|                 .cornerRadius(5.3) | ||||
|                 .padding(.top, 21.3) | ||||
|                  | ||||
|                 Text("콘텐츠를 \(orderType == .RENTAL ? "대여" : "소장")하시겠습니까?\n아래 캔이 차감됩니다.") | ||||
|                 Text("콘텐츠를 \(orderType == .RENTAL ? "대여" : "소장")하시겠습니까?") | ||||
|                     .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                     .foregroundColor(Color.grayee) | ||||
|                     .fixedSize(horizontal: false, vertical: true) | ||||
|                     .multilineTextAlignment(.center) | ||||
|                     .padding(.top, 13.3) | ||||
|                  | ||||
|                 if UserDefaults.int(forKey: .userId) != 17958 { | ||||
|                     Text("아래 캔이 차감됩니다.") | ||||
|                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                         .foregroundColor(Color.grayee) | ||||
|                         .fixedSize(horizontal: false, vertical: true) | ||||
|                         .multilineTextAlignment(.center) | ||||
|                         .padding(.top, 13.3) | ||||
|                 } | ||||
|                  | ||||
|                 HStack(spacing: 2.7) { | ||||
|                     Spacer() | ||||
|                      | ||||
|                     Image("ic_can") | ||||
|                         .resizable() | ||||
|                         .frame(width: 16.7, height: 16.7) | ||||
|                      | ||||
|                     if orderType == .RENTAL { | ||||
|                         Text("\(isOnlyRental ? audioContent.price : Int(ceil(Double(audioContent.price) * 0.6)))") | ||||
|                             .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                  | ||||
|                     if UserDefaults.int(forKey: .userId) != 17958 { | ||||
|                         Image("ic_can") | ||||
|                             .resizable() | ||||
|                             .frame(width: 16.7, height: 16.7) | ||||
|                          | ||||
|                         if orderType == .RENTAL { | ||||
|                             Text("\(isOnlyRental ? audioContent.price : Int(ceil(Double(audioContent.price) * 0.6)))") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                         } else { | ||||
|                             Text("\(audioContent.price)") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                         } | ||||
|                     } else { | ||||
|                         Text("\(audioContent.price)") | ||||
|                             .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                             .foregroundColor(Color(hex: "eeeeee")) | ||||
|                         if orderType == .RENTAL { | ||||
|                             Text("\(isOnlyRental ? audioContent.price * 110 : Int(ceil(Double(audioContent.price) * 0.6)) * 110)원") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                         } else { | ||||
|                             Text("\(audioContent.price * 110)원") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                         } | ||||
|                     } | ||||
|                      | ||||
|                     Spacer() | ||||
|                 } | ||||
|                 .padding(.vertical, 13.3) | ||||
|                 .background(Color(hex: "333333")) | ||||
|                 .background(Color.gray33) | ||||
|                 .cornerRadius(6.7) | ||||
|                 .overlay( | ||||
|                     RoundedRectangle(cornerRadius: CGFloat(6.7)) | ||||
|                         .stroke(lineWidth: 1) | ||||
|                         .foregroundColor(Color(hex: "979797")) | ||||
|                         .foregroundColor(Color.gray97) | ||||
|                 ) | ||||
|                 .padding(.top, 13.3) | ||||
|                  | ||||
|                 HStack(spacing: 12) { | ||||
|                     Text("취소") | ||||
|                         .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                         .foregroundColor(Color(hex: "9970ff")) | ||||
|                         .foregroundColor(Color.button) | ||||
|                         .padding(.vertical, 15.7) | ||||
|                         .frame(maxWidth: .infinity) | ||||
|                         .contentShape(Rectangle()) | ||||
|                         .overlay( | ||||
|                             RoundedRectangle(cornerRadius: CGFloat(10)) | ||||
|                                 .stroke(lineWidth: 1) | ||||
|                                 .foregroundColor(Color(hex: "9970ff")) | ||||
|                                 .foregroundColor(Color.button) | ||||
|                         ) | ||||
|                         .onTapGesture { isShowing = false } | ||||
|                      | ||||
| @@ -131,7 +153,8 @@ struct ContentOrderConfirmDialogView: View { | ||||
|                         .foregroundColor(.white) | ||||
|                         .padding(.vertical, 15.7) | ||||
|                         .frame(maxWidth: .infinity) | ||||
|                         .background(Color(hex: "9970ff")) | ||||
|                         .contentShape(Rectangle()) | ||||
|                         .background(Color.button) | ||||
|                         .cornerRadius(10) | ||||
|                         .onTapGesture { | ||||
|                             onClickConfirm() | ||||
| @@ -143,7 +166,7 @@ struct ContentOrderConfirmDialogView: View { | ||||
|             .padding(.horizontal, 13.3) | ||||
|             .padding(.top, 26.7) | ||||
|             .padding(.bottom, 16.7) | ||||
|             .background(Color(hex: "222222")) | ||||
|             .background(Color.gray22) | ||||
|             .cornerRadius(10) | ||||
|             .padding(.horizontal, 20) | ||||
|         } | ||||
|   | ||||
| @@ -40,17 +40,25 @@ struct ContentOrderDialogView: View { | ||||
|                         Spacer() | ||||
|                          | ||||
|                         HStack(spacing: 8) { | ||||
|                             Image("ic_can") | ||||
|                                 .resizable() | ||||
|                                 .frame(width: 16.7, height: 16.7) | ||||
|                             if UserDefaults.int(forKey: .userId) != 17958 { | ||||
|                                 Image("ic_can") | ||||
|                                     .resizable() | ||||
|                                     .frame(width: 16.7, height: 16.7) | ||||
|                             } | ||||
|                              | ||||
|                             Text(isOnlyRental ? "\(price)" : "\(Int(ceil(Double(price) * 0.6)))") | ||||
|                             Text(isOnlyRental ? "\(price * 110)" : "\(Int(ceil(Double(price) * 0.6)) * 110)") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                 .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                 .foregroundColor(Color.grayee) | ||||
|                              | ||||
|                             if UserDefaults.int(forKey: .userId) == 17958 { | ||||
|                                 Text("원") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                             } | ||||
|                         } | ||||
|                         .padding(.vertical, 8) | ||||
|                         .padding(.horizontal, 13.3) | ||||
|                         .background(Color(hex: "9970ff")) | ||||
|                         .background(Color.button) | ||||
|                         .cornerRadius(5.3) | ||||
|                         .onTapGesture { | ||||
|                             onTapPurchase(.RENTAL) | ||||
| @@ -73,17 +81,25 @@ struct ContentOrderDialogView: View { | ||||
|                             Spacer() | ||||
|                              | ||||
|                             HStack(spacing: 8) { | ||||
|                                 Image("ic_can") | ||||
|                                     .resizable() | ||||
|                                     .frame(width: 16.7, height: 16.7) | ||||
|                                 if UserDefaults.int(forKey: .userId) != 17958 { | ||||
|                                     Image("ic_can") | ||||
|                                         .resizable() | ||||
|                                         .frame(width: 16.7, height: 16.7) | ||||
|                                 } | ||||
|                                  | ||||
|                                 Text("\(price)") | ||||
|                                 Text("\(price * 110)") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                                  | ||||
|                                 if UserDefaults.int(forKey: .userId) == 17958 { | ||||
|                                     Text("원") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 13.3)) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                             } | ||||
|                             .padding(.vertical, 8) | ||||
|                             .padding(.horizontal, 13.3) | ||||
|                             .background(Color(hex: "9970ff")) | ||||
|                             .background(Color.button) | ||||
|                             .cornerRadius(5.3) | ||||
|                             .onTapGesture { | ||||
|                                 onTapPurchase(.KEEP) | ||||
| @@ -93,7 +109,7 @@ struct ContentOrderDialogView: View { | ||||
|                     } | ||||
|                 } | ||||
|                 .padding(24) | ||||
|                 .background(Color(hex: "222222")) | ||||
|                 .background(Color.gray22) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -187,6 +187,10 @@ struct ContentView: View { | ||||
|             case .seriesContentAll(let seriesId, let seriesTitle): | ||||
|                 SeriesContentAllView(seriesId: seriesId, seriesTitle: seriesTitle) | ||||
|                  | ||||
|             case .tempCanPayment(let title, let can, let onSuccess): | ||||
|                 CanPaymentTempView(title: title, can: can, onSuccess: onSuccess) | ||||
|                  | ||||
|                  | ||||
|             default: | ||||
|                 EmptyView() | ||||
|                     .frame(width: 0, height: 0, alignment: .topLeading) | ||||
|   | ||||
| @@ -86,11 +86,11 @@ struct CanPgPaymentView: View { | ||||
|                                      | ||||
|                                     Text("\(canResponse.price) 원") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 15.3)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                                 .padding(.horizontal, 13.3) | ||||
|                                 .padding(.vertical, 23.3) | ||||
|                                 .background(Color(hex: "222222")) | ||||
|                                 .background(Color.gray22) | ||||
|                                 .cornerRadius(16.7) | ||||
|                                 .padding(.horizontal, 13.3) | ||||
|                                 .frame(width: screenSize().width) | ||||
| @@ -98,7 +98,7 @@ struct CanPgPaymentView: View { | ||||
|                                  | ||||
|                                 Text("결제 수단 선택") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                                     .frame(width: screenSize().width - 26.7, alignment: .leading) | ||||
|                                     .padding(.top, 26.7) | ||||
|                                  | ||||
| @@ -106,18 +106,19 @@ struct CanPgPaymentView: View { | ||||
|                                 HStack(spacing: 13.3) { | ||||
|                                     Text("카드") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .card ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(Color(hex: viewModel.paymentMethod == .card ? "9970ff" : "eeeeee")) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .card ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             Color(hex: viewModel.paymentMethod == .card ? "9970ff" : "232323") | ||||
|                                                 .opacity(viewModel.paymentMethod == .card ? 0.3 : 1) | ||||
|                                             viewModel.paymentMethod == .card ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(Color(hex: viewModel.paymentMethod == .card ? "9970ff" : "777777")) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .card ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .card { | ||||
| @@ -128,18 +129,19 @@ struct CanPgPaymentView: View { | ||||
|                                      | ||||
|                                     Text("계좌이체") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .bank ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(Color(hex: viewModel.paymentMethod == .bank ? "9970ff" : "eeeeee")) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .bank ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             Color(hex: viewModel.paymentMethod == .bank ? "9970ff" : "232323") | ||||
|                                                 .opacity(viewModel.paymentMethod == .bank ? 0.3 : 1) | ||||
|                                             viewModel.paymentMethod == .bank ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(Color(hex: viewModel.paymentMethod == .bank ? "9970ff" : "777777")) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .bank ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .bank { | ||||
| @@ -153,18 +155,19 @@ struct CanPgPaymentView: View { | ||||
|                                 HStack(spacing: 13.3) { | ||||
|                                     Text("휴대폰 결제") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .phone ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(Color(hex: viewModel.paymentMethod == .phone ? "9970ff" : "eeeeee")) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .phone ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             Color(hex: viewModel.paymentMethod == .phone ? "9970ff" : "232323") | ||||
|                                                 .opacity(viewModel.paymentMethod == .phone ? 0.3 : 1) | ||||
|                                             viewModel.paymentMethod == .phone ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(Color(hex: viewModel.paymentMethod == .phone ? "9970ff" : "777777")) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .phone ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .phone { | ||||
| @@ -184,7 +187,7 @@ struct CanPgPaymentView: View { | ||||
|                                      | ||||
|                                     Text("구매조건 확인 및 결제 진행 동의") | ||||
|                                         .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                                 .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
|                                 .padding(.top, 16.7) | ||||
| @@ -196,11 +199,11 @@ struct CanPgPaymentView: View { | ||||
|                                     HStack(alignment: .top, spacing: 0) { | ||||
|                                         Text("- ") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                          | ||||
|                                         Text("충전된 캔의 유효기간은 충전 후 5년 입니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                             .fixedSize(horizontal: false, vertical: true) | ||||
|                                     } | ||||
|                                     .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
| @@ -209,11 +212,11 @@ struct CanPgPaymentView: View { | ||||
|                                     HStack(alignment: .top, spacing: 0) { | ||||
|                                         Text("- ") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                          | ||||
|                                         Text("결제 취소는 결제 후 7일 이내에만 할 수 있습니다.\n단, 캔의 일부를 사용하면 결제 취소를 할 수 없습니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                             .fixedSize(horizontal: false, vertical: true) | ||||
|                                     } | ||||
|                                     .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
| @@ -221,11 +224,11 @@ struct CanPgPaymentView: View { | ||||
|                                     HStack(alignment: .top, spacing: 0) { | ||||
|                                         Text("- ") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                          | ||||
|                                         Text("광고성 이벤트 등 회사가 무료로 지급한 포인트는 환불되지 않습니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                             .fixedSize(horizontal: false, vertical: true) | ||||
|                                     } | ||||
|                                     .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
| @@ -233,11 +236,11 @@ struct CanPgPaymentView: View { | ||||
|                                     HStack(alignment: .top, spacing: 0) { | ||||
|                                         Text("- ") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                          | ||||
|                                         Text("자세한 내용은 소다라이브 이용약관에서 확인할 수 있습니다.") | ||||
|                                             .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                             .foregroundColor(Color(hex: "777777")) | ||||
|                                             .foregroundColor(Color.gray77) | ||||
|                                             .fixedSize(horizontal: false, vertical: true) | ||||
|                                     } | ||||
|                                     .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
| @@ -251,12 +254,12 @@ struct CanPgPaymentView: View { | ||||
|                             VStack(alignment: .leading, spacing: 5) { | ||||
|                                 Text("결제금액") | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                     .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                                  | ||||
|                                 HStack(spacing: 0) { | ||||
|                                     Text("\(canResponse.price) 원") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 23.3)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                             } | ||||
|                              | ||||
| @@ -267,7 +270,7 @@ struct CanPgPaymentView: View { | ||||
|                                 .foregroundColor(.white) | ||||
|                                 .padding(.vertical, 16) | ||||
|                                 .frame(minWidth: 200) | ||||
|                                 .background(Color(hex: "9970ff")) | ||||
|                                 .background(Color.button) | ||||
|                                 .cornerRadius(10) | ||||
|                                 .onTapGesture { | ||||
|                                     if viewModel.paymentMethod == nil { | ||||
| @@ -290,12 +293,12 @@ struct CanPgPaymentView: View { | ||||
|                         .padding(.leading, 22) | ||||
|                         .padding(.trailing, 13.3) | ||||
|                         .padding(.vertical, 13.3) | ||||
|                         .background(Color(hex: "222222")) | ||||
|                         .background(Color.gray22) | ||||
|                         .cornerRadius(16.7, corners: [.topLeft, .topRight]) | ||||
|                          | ||||
|                         if proxy.safeAreaInsets.bottom > 0 { | ||||
|                             Rectangle() | ||||
|                                 .foregroundColor(Color(hex: "222222")) | ||||
|                                 .foregroundColor(Color.gray22) | ||||
|                                 .frame(width: proxy.size.width, height: 15.3) | ||||
|                         } | ||||
|                     } | ||||
| @@ -308,7 +311,7 @@ struct CanPgPaymentView: View { | ||||
|                                     .padding(.horizontal, 6.7) | ||||
|                                     .frame(width: geo.size.width - 66.7, alignment: .center) | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                     .background(Color(hex: "9970ff")) | ||||
|                                     .background(Color.button) | ||||
|                                     .foregroundColor(Color.white) | ||||
|                                     .multilineTextAlignment(.leading) | ||||
|                                     .fixedSize(horizontal: false, vertical: true) | ||||
| @@ -326,25 +329,6 @@ struct CanPgPaymentView: View { | ||||
|                 LoadingView() | ||||
|             } | ||||
|         } | ||||
|         .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { | ||||
|             GeometryReader { geo in | ||||
|                 HStack { | ||||
|                     Spacer() | ||||
|                     Text(viewModel.errorMessage) | ||||
|                         .padding(.vertical, 13.3) | ||||
|                         .padding(.horizontal, 6.7) | ||||
|                         .frame(width: geo.size.width - 66.7, alignment: .center) | ||||
|                         .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                         .background(Color(hex: "9970ff")) | ||||
|                         .foregroundColor(Color.white) | ||||
|                         .multilineTextAlignment(.leading) | ||||
|                         .fixedSize(horizontal: false, vertical: true) | ||||
|                         .cornerRadius(20) | ||||
|                         .padding(.top, 66.7) | ||||
|                     Spacer() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,12 @@ | ||||
| // | ||||
| //  CanChargeTempRequest.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 5/20/24. | ||||
| // | ||||
|  | ||||
| struct CanChargeTempRequest: Encodable { | ||||
|     let can: Int | ||||
|     let price: Int | ||||
|     let paymentGateway: PaymentGateway | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| // | ||||
| //  CanPaymentTempRepository.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 5/20/24. | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
| import CombineMoya | ||||
| import Combine | ||||
| import Moya | ||||
|  | ||||
| class CanPaymentTempRepository { | ||||
|     private let api = MoyaProvider<CanTempApi>() | ||||
|      | ||||
|     func chargeCan(request: CanChargeTempRequest) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.chargeCan(request: request)) | ||||
|     } | ||||
|      | ||||
|     func pgVerify(receiptId: String, orderId: String) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.verify(request: PgVerifyRequest(receiptId: receiptId, orderId: orderId))) | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,275 @@ | ||||
| // | ||||
| //  CanPaymentTempView.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 5/20/24. | ||||
| // | ||||
|  | ||||
| import SwiftUI | ||||
| import Bootpay | ||||
| import BootpayUI | ||||
|  | ||||
| struct CanPaymentTempView: View { | ||||
|      | ||||
|     @StateObject var viewModel = CanPaymentTempViewModel() | ||||
|      | ||||
|     let title: String | ||||
|     let can: Int | ||||
|     let onSuccess: () -> Void | ||||
|      | ||||
|     init(title: String, can: Int, onSuccess: @escaping () -> Void) { | ||||
|         self.title = title | ||||
|         self.can = can | ||||
|         self.onSuccess = onSuccess | ||||
|     } | ||||
|      | ||||
|     var body: some View { | ||||
|         ZStack { | ||||
|             Color.black.ignoresSafeArea() | ||||
|              | ||||
|             if viewModel.isShowPaymentView { | ||||
|                 BootpayUI(payload: viewModel.payload, requestType: BootpayRequest.TYPE_PAYMENT) | ||||
|                     .onConfirm { | ||||
|                         DEBUG_LOG("onConfirm: \($0)") | ||||
|                         return true | ||||
|                     } | ||||
|                     .onCancel { | ||||
|                         DEBUG_LOG("onCancel: \($0)") | ||||
|                     } | ||||
|                     .onError { | ||||
|                         DEBUG_LOG("onError: \($0)") | ||||
|                         viewModel.isShowPaymentView = false | ||||
|                         viewModel.errorMessage = "결제 중 오류가 발생했습니다." | ||||
|                         viewModel.isShowPopup = true | ||||
|                     } | ||||
|                     .onDone { | ||||
|                         DEBUG_LOG("onDone: \($0)") | ||||
|                         viewModel.verifyPayment($0) { | ||||
|                             let can = UserDefaults.int(forKey: .can) | ||||
|                             UserDefaults.set(can + self.can, forKey: .can) | ||||
|                              | ||||
|                             DispatchQueue.main.asyncAfter(deadline: .now() + 1) { | ||||
|                                 AppState.shared.back() | ||||
|                                 onSuccess() | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     .onClose { | ||||
|                         DEBUG_LOG("onClose") | ||||
|                         viewModel.isShowPaymentView = false | ||||
|                     } | ||||
|             } else { | ||||
|                 GeometryReader { proxy in | ||||
|                     VStack(spacing: 0) { | ||||
|                         DetailNavigationBar(title: "결제하기") | ||||
|                          | ||||
|                         ScrollView(.vertical, showsIndicators: false) { | ||||
|                             VStack(spacing: 0) { | ||||
|                                 HStack(spacing: 0) {                                     | ||||
|                                     Text(self.title) | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 15.3)) | ||||
|                                         .foregroundColor(Color(hex: "eeeeee")) | ||||
|                                         .padding(.leading, 13.3) | ||||
|                                      | ||||
|                                     Spacer() | ||||
|                                      | ||||
|                                     Text("\(self.can * 110) 원") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 15.3)) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                                 .padding(.horizontal, 13.3) | ||||
|                                 .padding(.vertical, 23.3) | ||||
|                                 .background(Color.gray22) | ||||
|                                 .cornerRadius(16.7) | ||||
|                                 .padding(.horizontal, 13.3) | ||||
|                                 .frame(width: screenSize().width) | ||||
|                                 .padding(.top, 13.3) | ||||
|                                  | ||||
|                                 Text("결제 수단 선택") | ||||
|                                     .font(.custom(Font.bold.rawValue, size: 16.7)) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                                     .frame(width: screenSize().width - 26.7, alignment: .leading) | ||||
|                                     .padding(.top, 26.7) | ||||
|                                  | ||||
|                                  | ||||
|                                 HStack(spacing: 13.3) { | ||||
|                                     Text("카드") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .card ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .card ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             viewModel.paymentMethod == .card ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .card ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .card { | ||||
|                                                 viewModel.paymentMethod = .card | ||||
|                                             } | ||||
|                                         } | ||||
|                                      | ||||
|                                      | ||||
|                                     Text("계좌이체") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .bank ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .bank ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             viewModel.paymentMethod == .bank ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .bank ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .bank { | ||||
|                                                 viewModel.paymentMethod = .bank | ||||
|                                             } | ||||
|                                         } | ||||
|                                 } | ||||
|                                 .frame(width: screenSize().width - 26.7) | ||||
|                                 .padding(.top, 16.7) | ||||
|                                  | ||||
|                                 HStack(spacing: 13.3) { | ||||
|                                     Text("휴대폰 결제") | ||||
|                                         .font(.custom( viewModel.paymentMethod == .phone ? Font.bold.rawValue : Font.medium.rawValue, size: 16.7)) | ||||
|                                         .foregroundColor(viewModel.paymentMethod == .phone ? Color.button : Color.grayee) | ||||
|                                         .frame(width: (screenSize().width - 40) / 2) | ||||
|                                         .padding(.vertical, 16.7) | ||||
|                                         .background( | ||||
|                                             viewModel.paymentMethod == .phone ? | ||||
|                                             Color.button.opacity(0.3) : | ||||
|                                                 Color.gray23 | ||||
|                                         ) | ||||
|                                         .cornerRadius(10) | ||||
|                                         .overlay( | ||||
|                                             RoundedRectangle(cornerRadius: 10) | ||||
|                                                 .stroke(lineWidth: 1) | ||||
|                                                 .foregroundColor(viewModel.paymentMethod == .phone ? Color.button : Color.gray77) | ||||
|                                         ) | ||||
|                                         .onTapGesture { | ||||
|                                             if viewModel.paymentMethod != .phone { | ||||
|                                                 viewModel.paymentMethod = .phone | ||||
|                                             } | ||||
|                                         } | ||||
|                                      | ||||
|                                     Spacer() | ||||
|                                 } | ||||
|                                 .frame(width: screenSize().width - 26.7) | ||||
|                                 .padding(.top, 16.7) | ||||
|                                  | ||||
|                                 HStack(spacing: 6.7) { | ||||
|                                     Image(viewModel.isTermsAgree ? "btn_select_checked" : "btn_select_normal") | ||||
|                                         .resizable() | ||||
|                                         .frame(width: 20, height: 20) | ||||
|                                      | ||||
|                                     Text("구매조건 확인 및 결제 진행 동의") | ||||
|                                         .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                                 .frame(width: screenSize().width - 53.4, alignment: .leading) | ||||
|                                 .padding(.top, 16.7) | ||||
|                                 .onTapGesture { | ||||
|                                     viewModel.isTermsAgree.toggle() | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                          | ||||
|                         Spacer() | ||||
|                          | ||||
|                         HStack(spacing: 0) { | ||||
|                             VStack(alignment: .leading, spacing: 5) { | ||||
|                                 Text("결제금액") | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                                  | ||||
|                                 HStack(spacing: 0) { | ||||
|                                     Text("\(self.can * 110) 원") | ||||
|                                         .font(.custom(Font.bold.rawValue, size: 23.3)) | ||||
|                                         .foregroundColor(Color.grayee) | ||||
|                                 } | ||||
|                             } | ||||
|                              | ||||
|                             Spacer() | ||||
|                              | ||||
|                             Text("결제하기") | ||||
|                                 .font(.custom(Font.bold.rawValue, size: 18.3)) | ||||
|                                 .foregroundColor(.white) | ||||
|                                 .padding(.vertical, 16) | ||||
|                                 .frame(minWidth: 200) | ||||
|                                 .background(Color.button) | ||||
|                                 .cornerRadius(10) | ||||
|                                 .onTapGesture { | ||||
|                                     if viewModel.paymentMethod == nil { | ||||
|                                         viewModel.errorMessage = "결제수단을 선택해 주세요." | ||||
|                                         viewModel.isShowPopup = true | ||||
|                                     } else if !viewModel.isTermsAgree { | ||||
|                                         viewModel.errorMessage = "결제진행에 동의하셔야 결제가 가능합니다." | ||||
|                                         viewModel.isShowPopup = true | ||||
|                                     } else { | ||||
|                                         viewModel.chargeCan(can: can, paymentGateway: .PG){ | ||||
|                                             viewModel.payload.orderName = self.title | ||||
|                                             viewModel.payload.price = Double(self.can * 110) | ||||
|                                             viewModel.payload.taxFree = 0 | ||||
|                                              | ||||
|                                             viewModel.isShowPaymentView = true | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                         } | ||||
|                         .padding(.leading, 22) | ||||
|                         .padding(.trailing, 13.3) | ||||
|                         .padding(.vertical, 13.3) | ||||
|                         .background(Color.gray22) | ||||
|                         .cornerRadius(16.7, corners: [.topLeft, .topRight]) | ||||
|                          | ||||
|                         if proxy.safeAreaInsets.bottom > 0 { | ||||
|                             Rectangle() | ||||
|                                 .foregroundColor(Color.gray22) | ||||
|                                 .frame(width: proxy.size.width, height: 15.3) | ||||
|                         } | ||||
|                     } | ||||
|                     .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { | ||||
|                         GeometryReader { geo in | ||||
|                             HStack { | ||||
|                                 Spacer() | ||||
|                                 Text(viewModel.errorMessage) | ||||
|                                     .padding(.vertical, 13.3) | ||||
|                                     .padding(.horizontal, 6.7) | ||||
|                                     .frame(width: geo.size.width - 66.7, alignment: .center) | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 12)) | ||||
|                                     .background(Color.button) | ||||
|                                     .foregroundColor(Color.white) | ||||
|                                     .multilineTextAlignment(.leading) | ||||
|                                     .fixedSize(horizontal: false, vertical: true) | ||||
|                                     .cornerRadius(20) | ||||
|                                     .padding(.top, 66.7) | ||||
|                                 Spacer() | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     .edgesIgnoringSafeArea(.bottom) | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             if viewModel.isLoading { | ||||
|                 LoadingView() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #Preview { | ||||
|     CanPaymentTempView(title: "콘텐츠 제목", can: 1000, onSuccess: {}) | ||||
| } | ||||
| @@ -0,0 +1,129 @@ | ||||
| // | ||||
| //  CanPaymentTempViewModel.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 5/20/24. | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
| import Combine | ||||
|  | ||||
| import Bootpay | ||||
|  | ||||
| enum TempPaymentMethod: String { | ||||
|     case card = "카드" | ||||
|     case bank = "계좌이체" | ||||
|     case phone = "휴대폰" | ||||
| } | ||||
|  | ||||
| final class CanPaymentTempViewModel: ObservableObject { | ||||
|   | ||||
|     private let repository = CanPaymentTempRepository() | ||||
|     private var subscription = Set<AnyCancellable>() | ||||
|      | ||||
|     @Published var isTermsAgree = false | ||||
|     @Published var errorMessage = "" | ||||
|     @Published var isShowPopup = false | ||||
|     @Published var isLoading = false | ||||
|      | ||||
|     @Published var isShowPaymentView = false | ||||
|     @Published var paymentMethod: TempPaymentMethod? = nil | ||||
|      | ||||
|     let payload = Payload() | ||||
|      | ||||
|     func chargeCan(can: Int, paymentGateway: PaymentGateway, onSuccess: @escaping () -> Void) { | ||||
|         isLoading = true | ||||
|         repository.chargeCan(request: CanChargeTempRequest(can: can, price: can * 110, paymentGateway: paymentGateway)) | ||||
|             .sink { result in | ||||
|                 switch result { | ||||
|                 case .finished: | ||||
|                     DEBUG_LOG("finish") | ||||
|                 case .failure(let error): | ||||
|                     ERROR_LOG(error.localizedDescription) | ||||
|                 } | ||||
|             } receiveValue: { [unowned self] response in | ||||
|                 self.isLoading = false | ||||
|                 let responseData = response.data | ||||
|                  | ||||
|                 do { | ||||
|                     let jsonDecoder = JSONDecoder() | ||||
|                     let decoded = try jsonDecoder.decode(ApiResponse<CanChargeResponse>.self, from: responseData) | ||||
|                      | ||||
|                     if let data = decoded.data, decoded.success { | ||||
|                         let bootUser = BootUser() | ||||
|                         bootUser.userId = "\(UserDefaults.int(forKey: .userId))" | ||||
|                         bootUser.username = UserDefaults.string(forKey: .nickname) | ||||
|                          | ||||
|                         payload.applicationId = BOOTPAY_APP_ID | ||||
|                         payload.pg = "세틀뱅크" | ||||
|                         payload.orderId = "\(data.chargeId)" | ||||
|                         payload.method = paymentMethod!.rawValue | ||||
|                         payload.user = bootUser | ||||
|                          | ||||
|                         onSuccess() | ||||
|                     } else { | ||||
|                         if let message = decoded.message { | ||||
|                             self.errorMessage = message | ||||
|                         } else { | ||||
|                             self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                         } | ||||
|                          | ||||
|                         self.isShowPopup = true | ||||
|                     } | ||||
|                 } catch { | ||||
|                     self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                     self.isShowPopup = true | ||||
|                 } | ||||
|             } | ||||
|             .store(in: &subscription) | ||||
|     } | ||||
|      | ||||
|     func verifyPayment(_ data: [String: Any], onSuccess: @escaping () -> Void) { | ||||
|         isLoading = true | ||||
|          | ||||
|         let _data = data["data"] as? [String: Any] | ||||
|          | ||||
|         if let data = _data { | ||||
|             let receiptId = data["receipt_id"] as! String | ||||
|             let orderId = data["order_id"] as! String | ||||
|              | ||||
|             repository.pgVerify(receiptId: receiptId, orderId: orderId) | ||||
|                 .sink { result in | ||||
|                     switch result { | ||||
|                     case .finished: | ||||
|                         DEBUG_LOG("finish") | ||||
|                     case .failure(let error): | ||||
|                         ERROR_LOG(error.localizedDescription) | ||||
|                     } | ||||
|                 } receiveValue: { [unowned self] response in | ||||
|                     self.isLoading = false | ||||
|                     let responseData = response.data | ||||
|  | ||||
|                     do { | ||||
|                         let jsonDecoder = JSONDecoder() | ||||
|                         let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) | ||||
|  | ||||
|                         if decoded.success { | ||||
|                             onSuccess() | ||||
|                         } else { | ||||
|                             if let message = decoded.message { | ||||
|                                 self.errorMessage = message | ||||
|                             } else { | ||||
|                                 self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                             } | ||||
|  | ||||
|                             self.isShowPopup = true | ||||
|                         } | ||||
|                     } catch { | ||||
|                         self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." | ||||
|                         self.isShowPopup = true | ||||
|                     } | ||||
|                 } | ||||
|                 .store(in: &subscription) | ||||
|         } else { | ||||
|             isLoading = false | ||||
|             errorMessage = "본인인증 중 오류가 발생했습니다." | ||||
|             isShowPopup = true | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								SodaLive/Sources/MyPage/Can/Payment/Temp/CanTempApi.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								SodaLive/Sources/MyPage/Can/Payment/Temp/CanTempApi.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // | ||||
| //  CanTempApi.swift | ||||
| //  SodaLive | ||||
| // | ||||
| //  Created by klaus on 5/20/24. | ||||
| // | ||||
|  | ||||
| import Foundation | ||||
| import Moya | ||||
|  | ||||
| enum CanTempApi { | ||||
|     case chargeCan(request: CanChargeTempRequest) | ||||
|     case verify(request: PgVerifyRequest) | ||||
| } | ||||
|  | ||||
| extension CanTempApi: TargetType { | ||||
|     var baseURL: URL { | ||||
|         return URL(string: BASE_URL)! | ||||
|     } | ||||
|      | ||||
|     var path: String { | ||||
|         switch self { | ||||
|         case .chargeCan: | ||||
|             return "/charge/temp" | ||||
|              | ||||
|         case .verify: | ||||
|             return "/charge/temp/verify" | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     var method: Moya.Method { | ||||
|         switch self { | ||||
|         case .chargeCan, .verify: | ||||
|             return .post | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     var task: Task { | ||||
|         switch self { | ||||
|         case .chargeCan(let request): | ||||
|             return .requestJSONEncodable(request) | ||||
|              | ||||
|         case .verify(let request): | ||||
|             return .requestJSONEncodable(request) | ||||
|              | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     var headers: [String : String]? { | ||||
|         switch self { | ||||
|         default: | ||||
|             return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"] | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung