public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] string data,
                                                           [Table("transactions", "AzureWebJobsStorage")] CloudTable table, HttpRequestMessage req, TraceWriter log)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                log.Error("Webhook content empty.");
                return(req.CreateResponse(HttpStatusCode.OK));
            }

// #if !DEBUG
            req.Headers.TryGetValues("X-Hook-Signature", out var headers);
            var sign = headers?.FirstOrDefault();

            var secret = EnvironmentExtensions.GetEnvString("STARLING_WEBHOOK_SECRET");

            var(_, valid) = WebhookPayloadValidator.Validate(sign, secret, data);

            if (!valid)
            {
                log.Error("Webhook signature mismatch. Rejected.");
                return(req.CreateResponse(HttpStatusCode.OK));
            }
// #endif

            var payload = StarlingDeserialiser.WebhookPayload(data);

            var existing = await table.GetExistingTransaction(payload.AccountHolderUid, payload.Content.TransactionUid);

            if (existing != null)
            {
                log.Warning($"Transaction {existing.RowKey} already processed on {existing.Timestamp}.");
                return(req.CreateResponse(HttpStatusCode.OK));
            }

            var goalId     = EnvironmentExtensions.GetEnvString("STARLING_GOAL_ID");
            var remainder  = (long)(Math.Abs(payload.Content.Amount) * 100 % 100);
            var difference = 100 - remainder;

            var threshold = EnvironmentExtensions.GetEnvInt("ROUND_UP_THRESHOLD");

            if (remainder >= threshold)
            {
                await _httpClient.SavingsGoalsAddMoney(goalId, difference);
            }

            await table.SaveTransaction(payload.AccountHolderUid, payload.Content.TransactionUid, difference);

            return(req.CreateResponse(HttpStatusCode.OK));
        }
Example #2
0
 public void GetEnvInt_KeyNullEmptyWhitespace_ThrowsException(string val, Type exception)
 {
     Assert.Throws(exception, () => EnvironmentExtensions.GetEnvInt(val));
 }