stripe / stripe-go

Go library for the Stripe API.
https://stripe.com
MIT License
2.17k stars 460 forks source link

add support for RawRequest #1924

Closed xavdid-stripe closed 1 month ago

xavdid-stripe commented 1 month ago

Why?

As the v2 API is releasing soon, we want Go to be able to make requests against the new endpoints despite not having generated types.

What

This is a copy/paste of https://github.com/stripe/stripe-go/pull/1648 with a few key differences:

Because we no longer needed to supply default values for API mode, I could remove the function that handled that. I also adjusted tests that assumed you could set content-type and v1 / v2 independently (given that all v1 requests are form encoded and all v2 request are json).

Manual Testing

  1. Create a new folder, henceforth myfolder
  2. In myfolder/go.mod, paste:
module xavd.id/test/v2

go 1.22.4

require github.com/stripe/stripe-go/v79 v79.0.0
// may need to adjust this relative path for your filesystem:
replace github.com/stripe/stripe-go/v79 v79.0.0 => ../../../stripe-go
  1. In myfolder/main.go paste:
package main

import (
    "encoding/json"
    "fmt"

    "github.com/stripe/stripe-go/v79"
    "github.com/stripe/stripe-go/v79/form"
    "github.com/stripe/stripe-go/v79/rawrequest"
)

func do_thing() error {
    stripe.Key = "sk_test_..."

    payload := map[string]interface{}{
        "event_name": "hotdogs_eaten", // FIXME
        "payload": map[string]string{
            "value":              "123", 
            "stripe_customer_id": "cus_Quq8itmW58RMet", // FIXME
        },
    }

    // for a v2 request, json encode the payload
    body, err := json.Marshal(payload)
    if err != nil {
        return err
    }

    v2_resp, err := rawrequest.Post("/v2/billing/meter_events", string(body), nil)
    if err != nil {
        return err
    }

    var v2_response map[string]interface{}
    err = json.Unmarshal(v2_resp.RawJSON, &v2_response)
    if err != nil {
        return err
    }
    fmt.Printf("%#v\n", v2_response)

    // for a v1 request, form encode the payload
    formValues := &form.Values{}
    form.AppendTo(formValues, payload)
    content := formValues.Encode()

    v1_resp, err := rawrequest.Post("/v1/billing/meter_events", content, nil)
    if err != nil {
        return err
    }

    var v1_response map[string]interface{}
    err = json.Unmarshal(v1_resp.RawJSON, &v1_response)
    if err != nil {
        return err
    }
    fmt.Printf("%#v\n", v1_response)

    return nil
}

func main() {
    err := do_thing()
    if err != nil {
        fmt.Printf("Error: %s\n", err)
    }
}

Running that (with valid customer id and event name) should print 2 response bodies

See Also

xavdid-stripe commented 1 month ago

@jar-stripe updated the comment, test string body, and extra HTTP method validation in https://github.com/stripe/stripe-go/pull/1924/commits/a05ed2d66ee340ab603a045e3de9e98f2a522154! I noticed that CallRaw was actually a different call path and could use validation as well.