質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

0回答

239閲覧

stripeでサブスク決済処理の実装時カード情報を取得したい。

510_water

総合スコア0

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

2クリップ

投稿2024/09/06 11:35

編集2024/09/08 01:54

実現したいこと

有料会員機能実装するに当たってstripeでのサブスク継続課金処理、カード情報を取得、取得したカード情報はユーザー情報として保管し、変更削除をできるようにするのが最終着地です。

発生している問題・分からないこと

現在、stirpeで決済処理ができるようにはなっています。
その際にユーザーのステータスの切り替えを同時行なっております。
次のステップとしてアプリ側でユーザーに決済に使用中のカード情報の表示、ユーザーがカード情報変更、削除を出来るようにしたいのですが実装方法が分かりません。

該当のソースコード

Java

1@Service 2public class StripeService { 3private final UserRepository userRepository; 4 5public StripeService(UserRepository userRepository) { 6this.userRepository = userRepository; 7} 8 9public String processSessionCompleted(Event event) { 10Session session = (Session) event.getDataObjectDeserializer().getObject().get(); 11return session.getCustomerEmail(); 12} 13 14@Value("${stripe.api-key}") 15private String stripeApiKey; 16 17public String createStripeSession(String userName, HttpServletRequest httpServletRequest) throws StripeException { 18Stripe.apiKey = stripeApiKey; 19 20String requestUrl = new String(httpServletRequest.getRequestURL()); 21 22// リクエストURLを元にベースURLを設定 23String baseUrl = requestUrl.replaceAll("/membership/subscribe", ""); 24 25// 成功およびキャンセル時のURL設定 26String successUrl = baseUrl + "/membership/subscribe-success?session_id={CHECKOUT_SESSION_ID}"; 27String cancelUrl = baseUrl + "/membership/subscribe?error=payment_cancelled"; 28System.out.println(successUrl); 29System.out.println(cancelUrl); 30 31SessionCreateParams params = SessionCreateParams.builder() 32.addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD) 33.setMode(SessionCreateParams.Mode.SUBSCRIPTION) 34.setSuccessUrl(successUrl) 35.setCancelUrl(cancelUrl) 36.addLineItem( 37SessionCreateParams.LineItem.builder() 38.setPriceData( 39SessionCreateParams.LineItem.PriceData.builder() 40 .setCurrency("jpy") 41 .setUnitAmount(300L) 42 .setRecurring( 43 SessionCreateParams.LineItem.PriceData.Recurring.builder() 44 .setInterval( 45 SessionCreateParams.LineItem.PriceData.Recurring.Interval.MONTH) 46 .build()) 47 48 .setProductData( 49 SessionCreateParams.LineItem.PriceData.ProductData.builder() 50 .setName("NAGOYAMESHI") 51 .build()) 52 .build()) 53.setQuantity(1L) 54.build()) 55.build(); 56try { 57Session session = Session.create(params); 58return session.getId(); 59} catch (StripeException e) { 60e.printStackTrace(); 61return ""; 62} 63}

Java

1@Service 2public class MembershipService { 3 private final UserRepository userRepository; 4 private final RoleRepository roleRepository; 5 private final UserDetailsService userDetailsService; 6 private final StripeService stripeService; 7 private final UserService userService; 8 9 public MembershipService(UserRepository userRepository, RoleRepository roleRepository, 10 UserDetailsService userDetailsService, StripeService stripeService, UserService userService) { 11 this.userRepository = userRepository; 12 this.roleRepository = roleRepository; 13 this.userDetailsService = userDetailsService; 14 this.stripeService = stripeService; 15 this.userService = userService; 16 } 17 18 public void updateMembershipStatus(String email, String customerId) { 19 User user = userRepository.findByEmail(email); 20 if (user != null) { 21 Role paidMemberRole = roleRepository.findByName("ROLE_PAID_MEMBER"); 22 user.setRole(paidMemberRole); 23 user.setIsPaidMember(true); 24 25 try { 26 // カード情報の取得と保存 27 Customer customer = Customer.retrieve(customerId); 28 PaymentMethod paymentMethod = PaymentMethod 29 .retrieve(customer.getInvoiceSettings().getDefaultPaymentMethod()); 30 31 user.setCardLast4(paymentMethod.getCard().getLast4()); 32 user.setCardBrand(paymentMethod.getCard().getBrand()); 33 user.setCardExpMonth(paymentMethod.getCard().getExpMonth().intValue()); 34 user.setCardExpYear(paymentMethod.getCard().getExpYear().intValue()); 35 } catch (StripeException e) { 36 // エラーハンドリング 37 e.printStackTrace(); 38 } 39 40 userRepository.save(user); 41 } 42 } 43}

Java

1@Controller 2@RequestMapping("/membership") 3public class MembershipController { 4 private final StripeService stripeService; 5 private final MembershipService membershipService; 6 private final UserService userService; 7 8 public MembershipController(MembershipService membershipService, StripeService stripeService, 9 UserService userService) { 10 this.membershipService = membershipService; 11 this.stripeService = stripeService; 12 this.userService = userService; 13 } 14 15 @GetMapping("/subscribe") 16 public String showSubscribePage(Principal principal, HttpServletRequest request, 17 @RequestParam(required = false) String error, Model model) throws StripeException { 18 if (error != null && error.equals("payment_cancelled")) { 19 model.addAttribute("errorMessage", "決済がキャンセルされました。"); 20 } 21 String userName = principal.getName(); 22 String sessionId = stripeService.createStripeSession(userName, request); 23 model.addAttribute("sessionId", sessionId); 24 System.out.println(sessionId); 25 return "membership/subscribe"; 26 } 27 28 @PostMapping("/subscribe") 29 public String subscribe(Principal principal, HttpServletRequest request, Model model) throws StripeException { 30 String userName = principal.getName(); 31 String sessionId = stripeService.createStripeSession(userName, request); 32 model.addAttribute("sessionId", sessionId); 33 System.out.println(sessionId); 34 return "membership/subscribe"; 35 } 36 37 @GetMapping("/subscribe-success") 38 public String subscribeSuccess(@RequestParam("session_id") String sessionId, 39 Principal principal, Model model) { 40 try { 41 String userEmail = principal.getName(); 42 String customerId = stripeService.getCustomerIdFromSession(sessionId); 43 membershipService.updateMembershipStatus(userEmail, customerId); 44 return "redirect:/membership/info?session_id=" + sessionId; 45 } catch (StripeException e) { 46 // エラーハンドリング 47 e.printStackTrace(); 48 return "error-page"; 49 } 50 } 51 52 @GetMapping("/info") 53 public String showMembershipInfo(Principal principal, Model model, 54 @RequestParam(required = false) String session_id) throws StripeException { 55 User user = userService.findByEmail(principal.getName()); 56 model.addAttribute("user", user); 57 58 if (user.isPaidMember()) { 59 PaymentMethod paymentMethod = stripeService.getPaymentMethod(user.getStripeCustomerId()); 60 model.addAttribute("paymentMethod", paymentMethod); 61 } 62 63 if (session_id != null) { 64 model.addAttribute("paymentMessage", "決済が完了しました。"); 65 } 66 67 return "membership/info"; 68 } 69}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

以下の記事が私のやりたいことに一番近いものだと思うのですが、実際のコード等がないので、イメージができませんでした。
初回に支払いとカード登録の両方、後にも請求する
①アプリケーションが カード入力フォームを返す前に 空の Customerを作り、②支払いを表す PaymentIntentを生成する
③顧客のリクエストに対し、④Stripe Element(Stripe.js)を使ってカード入力フォームを返す
⑤顧客はカード情報をStripeに送信する
⑥Stripeがカード情報をCustomerに紐づける
⑦Stripeはカード情報から PaymentMethod を返す(アプリケーションはPaymentMethodは必須ではないので、サーバーに送らなくてもよい)

見ての通り、カード番号などセンシティブな情報はアプリケーションに送らず、トークン(PaymentMethod)という形でアプリケーションに送るため、アプリケーションはセンシティブな情報を保持せず、カード決済が行なえるという仕組みになっています。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

510_water

2024/09/07 00:08

すみません。質問内容言葉足りなかったですね。 stripe側で決済した際、アプリ課金がサブスクリプションのためユーザー側がどのカードで継続課金しているのか見えるようにするために、カード情報の表示をアプリケーションで行いたい。とういうのが決済時のカード情報の取得、と考えてます。そのカード情報の取得、表示ができず、どうしたらstripeから情報をもらって表示させられるかが分からない。ということです。
AbeTakashi

2024/09/07 06:38

参考 https://qiita.com/hideokamoto/items/0ea4fe01cac8c8ad8669 https://qiita.com/hideokamoto/items/d2ad3b1a3ec101c785a9 この辺が参考になったりしないでしょうか? 質問文は追加や修正ができるので、↑で書かれた内容も含めて修正や更新されるとピンポイントの回答やアドバイスが来るかもしれません。第三者視点だと現状がどのようになっていてるか? 何をしたいのか? 何が困ってるか? などがちょっとつかみにくいと思います。フロー図やキャプチャ画面なども使用されるとより伝わるかもしれません。 参考) https://teratail.com/help/question-tips
510_water

2024/09/09 00:33 編集

アドバイスありがとうございます。 参考サイトもありがとうございます。 私Next.js使ったことがなくて、スクールの課題でやっていることなので、Java使って実装することが目的です。 個人的にNext.jsを機会ができたら参考にしてみます。
AbeTakashi

2024/09/09 01:57

Teratailは手取り足取り教えてもらえるのはかなりの条件が揃ったときくらいであり、今回の質問内容だと残念ですがそれは期待できないと思います(日本国内でStripeはそこまで普及してませんし、かつ、StripeでJavaを使ってる人は少ないと思われるため)。 もしこのサイトでアドバイスを希望されるのであれば、まずは公式のドキュメントを見つつ、他の言語の利用例などのドキュメントなども参考にして、ご自身でできるところまでプログラミングするしかないと思います。使われてる言語がなんであろうと、やってることはAPIを叩いてそのレスポンスを受け取って、そのデータを処理するだけです。Java の場合はStripeからSDKが用意されていますが、実際の中身はほぼAPIを叩いてるだけのように思います。 さらっとJava SDKドキュメントみたところ、カードのリスト表示はSDKには組み込まれてないようで、APIのエンドポイントだけ書かれてました。もし、Javaで直接APIを叩いてみてエラーが出るとであれば、そのエラー内容を提示して質問されるといいかと思います。具体的なエラー内容を質問内容に含めれば、Stripeには詳しくなくてもJavaには詳しい方からの回答が期待できるのではないかと思います。
510_water

2024/09/12 02:49

ありがとうございます。 カスタマーポータル使ってみようとしてダメだったんですが、アドバイスからAPI使う方法調べてみてそちらの方向にチェンジでやってみたら、変更と削除出来るようになりました。
AbeTakashi

2024/09/12 04:22

良かったです。ぜひ具体的な解決方法をアンサーとして記載の上、「自己解決」としてこの質問をクローズして頂くと、同じ悩みにぶつかった人にも役に立つと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問