Credit Card Payment

I am trying to learn how to process Credit Card payments with Retool.

The only option seems to be paying for items charged with Stripe.

I am showing a screen capture from the docs. It does not show the amount of money and I am not sure if it works.

I tried the demo with my own credit card and it said it was invalid.

Has anyone tried to use this feature? Does it work?

Mike

follow bellow to create a new Stripe resource.

on your stripe admin dashboard you'll need to create a Restricted Key. You'll use this when creating the resource above (it'll require for an API key).

click 'Test connection' just to make sure you've entered your api key correctly.
back in your app, create a new Resource Query
image

you may need to refresh the page for the new Resource we made (i named mine StripeTest) to show up.
image

once it appears, just select it

when you change the 'Operation' you'll notice required Request Body parameters are automatically added. you can click 'Add parameter' to see a list of non-required parameters you can add.

Stripe payments API

if you want to use the component retool provides
image

you can select 'Create a new query`
from this new query, you can call the previous query that uses the Stripe Resource we created like

await stripeTestQuery.trigger({additionalScope:{ token: stripeCardForm1.stripeToken} })`

careful here, make sure there's a space between the 2 }'s otherwise the linter will think it's the closing of a JS block, which it isn't.
from stripeTestQuery we can use:

{{ token.id }} //stripe token id tok_123456789testtoken
{{ token.card }} //get card info, like token.card.id which holds the id for the card stored in stripe

Bob:

Just before I go to far down this road, is this something that only works with STRIPE payment requests.

I want something that will work with independent payment requests.

Mike

I suppose that'd depend on how independent payment requests is defined? Stripe does let you use external payment methods, but they also have a bunch of built-in integrations. you can check the table here, just scroll down a couple paragraphs till u see the chart thingy

table summarizes relevant payment methods supported on Stripe by business model

OK, thanks Bob:

I will give it a try.

Mike

hey @mdsmith1, i went ahead and made a test stripe account so i could get the query working for ya (stripe api is big and confusing, took me a little bit but I finally got payments being made).


this component is confusing and works a bit differently than you might expect. when you click the 'Submit' button, it actually creates a 'card' and initializes a new property of the component, in this case stripeCardForm1.stripeToken. this is automatic and it looks like it actually calls the POST /v1/token api endpoint, which means the On stripe token created query would normally use stripeCardForm1.stripeToken in the following requests (after a token is created, i think you need to attach the 'card' to a 'user' first, then you can charge it)
image

if you have your stripe dashboard in test mode you can use the test card:

card number: 4242 4242 4242 4242
expiration: 06/28
cvc: 000
zip: 66219

I went ahead and also got the stripe.js sdk/library loading in a custom component with the prebuilt buy button. the library is large, so I'd suggest using it in a similar way as below where you import specific components that you plan on using. just copy/paste the code below into the 'Iframe Code' and after everything loads you should see the button

<style>
  @import url('https://rsms.me/inter/inter.css');
  html { font-family: 'Inter', sans-serif; }
  @supports (font-variation-settings: normal) {
    html { font-family: 'Inter var', sans-serif; }
  }

  * {
    font-family: 'Inter', sans-serif;
  }

  body {
    margin: 0;
  }

  #react {
    height: 100%;
    width: 100%;
  }

  .card {
    min-width: 0;
    min-height: 120px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 12px 24px;
    border-radius: 4px;
    border: 1px solid #cccccc;
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
    background-color: var(--background-surface);
  }

  .title-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    line-height: 24px;
  }

  .title {
    font-size: 18px;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .docs-link {
    font-size: 12px;
    font-weight: 500;
    color: #b062bc;
    text-decoration: none;
  }


  
</style>

<!-- You can add any HTML/CSS/JS here. UMD versions are required.
Keep in mind that Custom Components are sensitive to bundle sizes, so try using a
custom implementation when possible. -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script async src="https://js.stripe.com/v3/buy-button.js" ></script>

<div id="react"></div>

<script type="text/babel">
  const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => (    
    <div className="card">
      <stripe-buy-button buy-button-id="buy_btn_1PWH0sAt3LkW1SlO6Rtpp55x" publishable-key="pk_test_51Klz4VAt3LkW1SlObx1INJMtohPTL8Sff08CmT3gsmCOlqhutn8sAhBwXka2SGVga7pSGFIqcHeJP6dh9eqNb2Bt00pTwYLZg9" />
    </div>
  )

  // This is the entrypoint for the React component.
  const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent)
  const container = document.getElementById('react')
  const root = ReactDOM.createRoot(container)
  root.render(<ConnectedComponent />)
</script>

image
you'll need to enable 'Storage and cookies' for the custom component before it renders. you may need other privilages depending how the stripe api works (personally, i try and avoid redirects, but you may need to enable 'Top level navigation' as well)

the one thing I haven't managed to get working is setting a workflow url as a stripe webhook. it attempts to make the calls to the workflow using the the webhook trigger (or alias if you have it set), but it keeps getting 401 errors. it'd probably work if you set the alias to public, but that might create a security nightmare so if you try it please be careful :beers:

1 Like

Bob:

Thank you so much for all your work on this.

I will see what I can do.

Thank you again.

Mike

1 Like

hey @mdsmith1, I just wanted to stop by and see if you got something working or if you needed any more help.

I must confess I have not had time to look at it. This is our Canada Day Weekend and we have had a lot of company.

I will be looking at it starting tomorrow.

Thanks.

Mike

1 Like

ah I see, well hope you have a great holiday weekend!! There's no rush over here at all!

Bob:

I have taken a look at this.

I cannot get started. This thing is far to complicated given my level of experience with Retool.

I will have to find another way of doing this.

Thanks for your prep work on this but I simply can't handle all the complex steps to do this.

Mike