#loren_api

1 messages Β· Page 1 of 1 (latest)

foggy warrenBOT
#

πŸ‘‹ Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

πŸ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1473737959827177715

πŸ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

vernal wedge
#

hello! looking at this now

#

i see this error on your test mode request:

This PaymentIntent requires a mandate, but no existing mandate was found. Collect mandate acceptance from the customer and try again, providing acceptance data in the mandate_data parameter.
is that the error you're getting in prod too?

quaint knoll
#

yes, same error

#

I can grab you a prod requestId too if you'd like

#

I can also paste our code for any of those sdk interactions, if that would be helpful

vernal wedge
#

yeah i think that would be helpful, as much code as you can share, especially for confirmAcssDebitSetup()

#

it does look like you're providing mandate data when setting up the payment method so nothing obvious is jumping out to me

quaint knoll
#

in order of the flow. This is first, we create the setup_intent like this, and return the client_secret to the front end code

#

the front end code (nextjs app) then calls the Stripe sdk like this

vernal wedge
#

can you share in code blocks (using triple backticks) instead of screenshots so i can copy paste?

quaint knoll
#

yes

#
  return stripe.setupIntents.create({
    customer: customerId,
    payment_method_types: ["acss_debit"],
    usage: "off_session",
    ...(connectedAccountId && { on_behalf_of: connectedAccountId }),
    payment_method_options: {
      acss_debit: {
        currency: "cad",
        verification_method: "automatic",
        mandate_options: {
          payment_schedule: "combined",
          interval_description: "Payments can be initiated at a pre-defined interval or sporadically",
          transaction_type: "business",
        },
      },
    },
  });
#
await stripe.confirmAcssDebitSetup(setupResult.setupIntent.client_secret, {
        payment_method: {
          billing_details: {
      name: selectedStore.detail?.name || "",
      email: user?.email || selectedStore.detail?.email || "",
    },
        },
      });
vernal wedge
#

ok, give me just a bit to test this, i actually don't have a test integration that uses confirmAcssDebitSetup yet so i'll need to modify an existing one

quaint knoll
#

and then once the payment method is attached, the user shops on the site and goes to check out, and we create an invoice to collect the payment

      const invoiceParams: Stripe.InvoiceCreateParams = {
        customer: stripeCustomerId,
        currency: currency?.toLowerCase() as any,
        collection_method: "charge_automatically",
        auto_advance: false, // Don't auto-advance, we'll pay it manually
        default_payment_method: paymentMethodId, // Attach the payment method
        custom_fields: [
          { name: "Pay To", value: `CrumblFoods` },
          ...(legalEntityName ? [{ name: "Legal Entity", value: String(legalEntityName).slice(0, 30) }] : []),
        ],
        metadata: {},
        payment_settings: {
          payment_method_types: ["acss_debit"],
        },
        shipping_cost: {
          shipping_rate_data: {
            display_name: inventoryOrder.shippingMethod || "Shipping",
            type: "fixed_amount",
            fixed_amount: {
              amount: shippingSubtotal || 0,
              currency: String(currency || "usd").toLowerCase() as any,
            },
          },
        },
        ...(stripeCrumblFoodsConnectedAccountId && {
          on_behalf_of: stripeCrumblFoodsConnectedAccountId,
          transfer_data: {
            destination: stripeCrumblFoodsConnectedAccountId,
          },
        }),
      };

      const invoice = await stripeClient.invoices.create(invoiceParams);
#

and then we add the invoice line items, finalize it, then pay it

#
      for (const li of lineItems) {
        const lineItemParams: Stripe.InvoiceItemCreateParams = {
          customer: stripeCustomerId,
          currency: String(currency || "usd").toLowerCase() as any,
          unit_amount: li.unitPrice,
          quantity: li.quantity,
          description: li.name || li.sku || "Item",
          invoice: invoice.id,
        } as any;
        await stripeClient.invoiceItems.create(lineItemParams);
      }
const finalizedInvoice = await stripeClient.invoices.finalizeInvoice(invoice.id);
      const paidInvoice = await stripeClient.invoices.pay(finalizedInvoice.id, {
        payment_method: paymentMethodId,
      });
#

yeah, no worries, take your time!

#

I appreciate the help

#

req_oCZykRSD88O92S
here is a production requestId in case you need that

foggy warrenBOT
half canyon
#

πŸ‘‹ I'll be taking over for solanum here, who needed to step away

quaint knoll
#

sounds good, thanks!

half canyon
#

Do you have an example / reproduction where you don't detach the payment method after failing to pay the Invoice?

quaint knoll
#

I'm not sure what you mean

#

we aren't doing that on purpose anywhere in the code

#

is there something with the way we're calling the stripe.invoice sdk that is causing that to happen?

half canyon
quaint knoll
#

oh, that's just us messing around with trying out different solutions

#

after the payment fails, we've been trying to re-attach the payment method to see if different approaches will get the mandate data to work properly

#

I can do a test transaction and then not detach the payment method after, if that's helpful

#

req_gsuyQJy9RVGkz0 here is a new one in sandbox!

#

I've told my team to not mess with that test customer anymore, so they won't attach or detach any payment methods for the time being

half canyon
quaint knoll
#

ah, intereseting. Let me give that a shot

half canyon
#

the mandate is stored on the SetupIntent

quaint knoll
#

that gives me a different error now

#

let me grab the latest requestId

half canyon
#

well that's something πŸ˜„

quaint knoll
#

You cannot provide both a mandate id and mandate information to payment_method_options

#

req_5uFBnpBb1tMt9a
here is the latest sandbox requestId

half canyon
#

what the

#

Okay, I think this is just broken.

#

I've reached out to our product team about it. If you can create a support ticket, then we can keep you updated on the fix

#

I can send you instructions via dm on creating a support case

foggy warrenBOT
#

Hello @quaint knoll, we have sent you a direct message, please check it at https://discord.com/channels/@me/1473760800752668866

  • πŸ”—The message has instructions on how to open a direct support case with our Developer Support team, in order to help you more effectively.
quaint knoll
#

we do have a support ticket going already, but we weren't making much headway there, which is why I reached out here as well. Should we try to link to that existing ticket, or create a new one?

half canyon
#

Ah; let me find that ticket

#

okay, I left a note explaining the situation in the support ticket, and I'll drop a note to the person who is handling it

quaint knoll
#

ok awesome, thanks for looking into it for me!

half canyon
#

Yeah, I'm sorry about that

quaint knoll
#

no worries! I'm glad we're getting the right eyes on it