Updating MetaData on Connected account fails - c#

I am using stripe connect(destination payment) with the help of stripe.net library from Jaymedavis.
The problem that I am facing is that I am not able to retrieve the destination payment ID to update the metadata in the connected account. The following line returns a null preventing me from updating meta data on the connected account. But the strange thing is that when I log in to the dashboard the destination payment ID exists. I am not sure why I am not able to retreive it in code.
Is the charge creation asynchronous?. I am not sure. Stripe's connect documentation does not help either. The following line returns a null. My code is down below. Seeking help.
String deschargeID = result.Transfer.DestinationPayment;
Here is the code that I am using
var service = new StripeChargeService(ZambreroSecretKey);
var result = (Stripe.StripeCharge) null;
try {
result = service.Create(newCharge);
if (result.Paid) {
//get the chargeID on the newgen account and update the metadata.
//Returns null even though it exists in the dashboard
String deschargeID = result.Transfer.DestinationPayment;
var chargeService = new StripeChargeService(newgenSecretKey);
StripeCharge charge = chargeService.Get(deschargeID);
charge.Metadata = myDict;
Response.Redirect("PgeCustSuccess.aspx?OrderID=" + OrderID);
}
} catch (StripeException stripeException) {
Debug.WriteLine(stripeException.Message);
stripe.Text = stripeException.Message;
}

The charge object's transfer attribute is not expanded by default, meaning it's just a string with the ID of the transfer object ("tr_..."), not a full transfer object.
According to Stripe.net's documentation, you can expand the transfer attribute by adding this line:
service.ExpandTransfer = True
before sending the charge creation request.

Related

C# Creation of DB on Firestore fails with no error message

I am following the docs on how to set up a backend with firestore:
https://firebase.google.com/docs/firestore/quickstart?authuser=0#c_1
I already set up a service account, genereted a key file and fed that into the code on my end. The connection works and I set the right permission (owner) to be able to read the bucket list.
But as soon as I try the first line of code from the tutorial:
FirestoreDb db = FirestoreDb.Create(project);
Console.WriteLine("Created Cloud Firestore client with project ID: {0}", project);
The execution dies. It doesnt lead to an error message, it doesnt run into a catch block with an exception. It just doesnt continue after the Create(project) part.
I noticed however, that the created datebase on the firebase console and the service account dont seem to be connected yet. Also, I dont know what to put for "project". I tried the project Id from the service account (with which i can do listbuckets) but this doesnt seem to work.
In the docs it does not state anything about what else to do.
Can you guys give me a hint maybe?
Thank you
EDIT:
LONGER CODE EXCEPT:
var credential = GoogleCredential.FromFile("/Users/juliustolksdorf/Projects/Interior Circle/keys/interiorcircle-4f70f209e160.json");
var storage = StorageClient.Create(credential);
// Make an authenticated API request.
var buckets = storage.ListBuckets("interiorcircle");
foreach (var bucket in buckets)
{
Console.WriteLine(bucket.Name);
}
var db = FirestoreDb.Create("interiorcircle");
DocumentReference docRef = db.Collection("users").Document("alovelace");
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "First", "Ada" },
{ "Last", "Lovelace" },
{ "Born", 1815 }
};
await docRef.SetAsync(user);
}
catch(Exception e)
{
DisplayAlert("hi", e.ToString(), "ok");
}
List buckets works, so the key is set correctly, but as soon as I try to do the create DB it fails.
You should refer to the Firestore .NET Client Documentation.
In order to connect, you should pass the projectId to FirestoreDb.Create and you should set and environment variable called GOOGLE_APPLICATION_CREDENTIALS which contains the path to your service account JSON file.
Edit:
You can also explicitly pass the credential to FirestoreDb, by using:
FirestoreDb db = new FirestoreDbBuilder { ProjectId = projectId, Credential = credential }.Build();

how to check if user already exists in firebase c#

I built a login/register system, and I want that when you create a username it checks if email exists, it works fine and it shows the message box "Email exists", but when it is a new user and there is no email that exists, it crashes.
Here is the exception message:
(System.NullReferenceException) Message=The object reference was not set to an object instance
Code:
FirebaseResponse response = await client.GetTaskAsync("Information/" + Emailtextbox.TextName);
Data result = response.ResultAs<Data>();
if (Emailtextbox.TextName == result.Email)
{
MessageBox.Show("Email exists");
} else
{
var data = new Data
{
Email = Emailtextbox.TextName,
Fullname = Fullnametextbox.TextName,
Password = EncryptSHA.GetShaData(PasswordTextbox.TextName)
}
};
Updating this based on the screenshot of the error as well as the information provided in the following comments.
It looks like your error has to do with what's being returned from your client.GetTaskAsync("Information/" + Emailtextbox.Textname); call.
My recommendation would be to try and understand what it is you're receiving from that call (what's stored in your response object). With the latest screenshot I see that the Body is null, and that might be part of the problem. Try expanding what you see in the Response object in your response and see if you're even receiving any kind of data you can use and go from there.

Expanding a Source object in a Stripe API call to StripeBalenceService doesn't return any customer info

I'm making a c# call to the Stripe.net API to fetch a balance history for a connected account. I'm trying to expand on the balance transaction object to see where the charge is coming from (ex. the customer who made the charge) as all the charges to connected accounts on my platform are from charge objects with a destination property to the connected account.
Here is my code and a screenshot of what the expanded source looks like, but think I should see a charge id or a customer or something refering me to the initial customer somewhere, but I don't...
var balanceService = new StripeBalanceService();
balanceService.ExpandSource = true;
var list = new List <string> () {
"data.source.source_transfer"
};
StripeList <StripeBalanceTransaction> balanceTransactions
= balanceService.List(
new StripeBalanceTransactionListOptions() {
Limit = 20,
Type = "payment",
Expand = list
},
new StripeRequestOptions() {
StripeConnectAccountId = accountId
}
);
foreach(var transaction in balanceTransactions) {
var test = transaction;
}
I feel like I should see a charge id (ex. ch_xxx) or a Customer value (which is null) all I see of any relevance is a payment id (ex. py_xxx)
It is possible to get the charge object(ch_xxx), it is just a little involved!
As you are using destination charges, the charge(ch_xxx) takes place on the platform account, and then a transfer(tr_xxx) is made to the connected account. That transfer creates a payment(py_xxx) on the connected account, which results in a balance transaction(txn_xxx).
As your code expands the source of those balance transactions, you get the payment(py_xxx). The payment is equivalent to a charge, so it has a source_transfer field. You can expand this field also! This will give you the transfer object(tr_xxx). Finally, the transfer has a source_transaction field, and this can be exapanded to give the original charge(ch_xxx)!
Putting that all together, you will want to expand on "data.source.source_transfer.source_transaction".
If you use a Stripe library in a dynamic language you can see this in action ... unfortunately, stripe-dotnet has an open issue right now which means that you can not do this directly. Instead, you will need to make the API calls manually by calling the various Retrieve functions on the IDs, instead of doing a single expansion. It would look something like this:
var paymentId = transaction.Source.Id;
var chargeService = new StripeChargeService();
var payment = chargeService.Get(
paymentId,
new StripeRequestOptions()
{
StripeConnectAccountId = accountId
}
);
var transferService = new StripeTransferService();
transferService.ExpandSourceTransaction = true;
var transfer = transferService.Get(payment.SourceTransferId);
var charge = transfer.SourceTransaction;
Console.WriteLine(charge.Id);

How to create a direct charge by using a shared customer?

I am attempting to create a direct charge to a connected account from my platform. I have been advised by Stripe support to do this by using a shared customer, however that has just created more issues.
The code itself is very simple, if it worked. It updates the platform customer with the src_... token provided by an iOS app. This works. It then attempts to create a shared customer using the StripeTokenService(). This does not work, despite following the documentation to the letter. The error I receive is:
You provided a customer without specifying a source. The default source of the customer is a source and cannot be shared from existing customers.
I can see no method of providing a source to the shared customer in the Stripe .Net SDK. All I can provide is a Card or BankAccount, neither of which I want to do as the API should remain agnostic of sensitive user information.
What exactly am I doing wrong here?
StripeConfiguration.SetApiKey(Settings.Stripe.SecretKey);
var businessRequestOptions = new StripeRequestOptions { StripeConnectAccountId = businessOwner.StripeAccountId };
var customerService = new StripeCustomerService();
customerService.Update(userDetail.StripeCustomerId, new StripeCustomerUpdateOptions
{
SourceToken = stripeToken // = 'src_...'
});
var tokenService = new StripeTokenService();
// this is the call that generates the error I mentioned above \/ \/
var token = tokenService.Create(new StripeTokenCreateOptions
{
CustomerId = userDetail.StripeCustomerId // = 'cus_...'
}, businessRequestOptions);
// create a direct charge to the business account (taking out application fee)
var chargeService = new StripeChargeService();
var stripeCharge = chargeService.Create(new StripeChargeCreateOptions
{
Amount = Convert.ToInt32(fee),
Currency = currency,
Description = $"Payment to {businessOwner.BusinessName} through Service X",
ApplicationFee = applicationFee,
SourceTokenOrExistingSourceId = token.Id, // use shared customerId here
}, businessRequestOptions);
When using Sources you have to use a different approach which is documented here: https://stripe.com/docs/sources/connect#shared-card-sources
The idea is that you are going to "clone" the Source from the platform to the connected account. This is done using the original_source when creating a new Source. You will then get a new Source object with a different id src_XXXX that you can then charge directly on the connected account.

NetSuite SuiteTalk TransactionSearchAdvanced: recordList equals null

I have a small C# console application who's sole purpose is to receive records from a "Saved Search" in NetSuite(via SuiteTalk). I've been able to successfully connect and receive records from NetSuite for my Saved Search(the search runs fine through the web interface too), however when I attempt to access the results of the "Saved Search" through my application, I am unable to view them because the search object that is returned does not contain any data in the "recordList" property:
//Connect
var dataCenterAwareNetSuiteService = new DataCenterAwareNetSuiteService("XXXXXX");
dataCenterAwareNetSuiteService.Timeout = 1000 * 60 * 60 * 2;
//Adds Credentials etc...
dataCenterAwareNetSuiteService.tokenPassport = createTokenPassport();
//Setup Preferences
var prefs = new Preferences();
prefs.warningAsErrorSpecified = true;
prefs.warningAsError = false;
dataCenterAwareNetSuiteService.preferences = prefs;
var searchPrefs = new SearchPreferences();
dataCenterAwareNetSuiteService.searchPreferences = searchPrefs;
dataCenterAwareNetSuiteService.searchPreferences.pageSize = 5;
dataCenterAwareNetSuiteService.searchPreferences.pageSizeSpecified = true;
dataCenterAwareNetSuiteService.searchPreferences.bodyFieldsOnly = false;
dataCenterAwareNetSuiteService.searchPreferences.returnSearchColumns = false;
//Search
var tranSearchAdv = new TransactionSearchAdvanced();
var tranSearchRow = new TransactionSearchRow();
var tranSearchRowBasic = new TransactionSearchRowBasic();
tranSearchAdv.savedSearchId = "XXXX";
tranSearchRowBasic.internalId =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRowBasic.tranId =
new SearchColumnStringField[] { new SearchColumnStringField() };
tranSearchRowBasic.dateCreated =
new SearchColumnDateField[] { new SearchColumnDateField() };
tranSearchRowBasic.total =
new SearchColumnDoubleField[] { new SearchColumnDoubleField() };
tranSearchRowBasic.entity =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRow.basic = tranSearchRowBasic;
tranSearchAdv.columns = tranSearchRow;
//No errors,
//this works correctly and returns the "Saved Search" with the correct "totalRecords"
//but results.recordList == null while results.totalRecords = 10000000+
var results = dataCenterAwareNetSuiteService.search(tranSearchAdv);
I appears to me that the "recordList" object is the principal way data is retrieved from the results of a search(Related Java Example, Another Here). This is also the way the example API does it.
I have run this on multiple "Saved Search's" with the same results. I don't understand how you can have more than one record in "totalRecords" and yet the "recordList" remains null? Is there some configuration option that has to be set to allow me to access this property. Or maybe it's a security thing, the API user I have setup should have full access, is there anything else that need to be granted access?
NetSuite SuiteTalk is not well documented, and most of the examples online are not in C#, and not dealing with the issues that I'm experiencing. These factors make it very difficult to determine why the previously mentioned behavior is occurring, or even, to discover any alternative methods for retrieving the resulting data from the source "Saved Search".
Does anyone have any insight into this behavior? Is this the correct method of retrieving results from SuiteTalk? Is there any configuration from the API or Web Side that needs to be changed?
Update 1
I've also tried using the alternative way of getting result data by accessing the "searchRowList" object from the "SearchResult" object(suggested by #AdolfoGarza) However it returns mostly empty fields(null) similar to the "recordList" property I do not see a way to retrieve "Saved Search" data from this method.
Try getting the results with results.searchRowList.searchRow , thats how it works in php.
I was able to resolve the issue by removing this line in the code:
tranSearchRow.basic = tranSearchRowBasic;
Then like #AdolfoGarza reccomended, retrieving the results from "basic" field in "results.searchRowList"
For some reason the template API that I was using was setting up a "TransactionSearchAdvanced" referencing a blank "TransactionSearchBasic" record, not sure why but this was causing the results from "searchRowList" to be null. After removing it I now get non-null values in the proper fields.
As for "recordList", it's still null, not sure why, but as I have my data I don't think I'll continue to dig into this.

Categories