I set up a Nuget package that does the shipments to Pagseguro, based on their Github:
https://www.nuget.org/packages/Uol.PagSeguro
The sources are here.
Creating a Request
These are the steps to create a basic request. The remaining examples should be considered using the example below as a basis.
    // Essa variável define se é o ambiente de teste ou produção.
    const bool isSandbox = true;
    EnvironmentConfiguration.ChangeEnvironment(isSandbox);
    try
    {
        var credentials = PagSeguroConfiguration.Credentials(isSandbox);
        // Instanciar uma nova requisição de pagamento
        var payment = new PaymentRequest {Currency = Currency.Brl};
        // Adicionar produtos
        payment.Items.Add(new Item("0001", "Notebook Prata", 1, 2430.00m));
        payment.Items.Add(new Item("0002", "Notebook Rosa", 2, 150.99m));
        // Código que identifica o pagamento
        payment.Reference = "REF1234";
        // Informações de entrega
        payment.Shipping = new Shipping
        {
            ShippingType = ShippingType.Sedex,
            Cost = 10.00m,
            Address = new Address(
                "BRA",
                "SP",
                "Sao Paulo",
                "Jardim Paulistano",
                "01452002",
                "Av. Brig. Faria Lima",
                "1384",
                "5o andar"
                )
        };
        // Informações do remetente
        payment.Sender = new Sender(
            "Joao Comprador", 
            "[email protected]", 
            new Phone("11", "56273440")
        );
        // URL a redirecionar o usuário após pagamento
        payment.RedirectUri = new Uri("http://www.lojamodelo.com.br");
        // Informações extras para identificar o pagamento.
        // Essas informações são livres para adicionar o que for necessário.
        payment.AddMetaData(MetaDataItemKeys.GetItemKeyByDescription("CPF do passageiro"), "123.456.789-09", 1);
        payment.AddMetaData("PASSENGER_PASSPORT", "23456", 1);
        // Outra forma de definir os parâmetros de pagamento.
        payment.AddParameter("senderBirthday", "07/05/1980");
        payment.AddIndexedParameter("itemColor", "verde", 1);
        payment.AddIndexedParameter("itemId", "0003", 3);
        payment.AddIndexedParameter("itemDescription", "Mouse", 3);
        payment.AddIndexedParameter("itemQuantity", "1", 3);
        payment.AddIndexedParameter("itemAmount", "200.00", 3);
        var senderCpf = new SenderDocument(Documents.GetDocumentByType("CPF"), "12345678909"); 
        payment.Sender.Documents.Add(senderCpf);
        var paymentRedirectUri = payment.Register(credentials);
        Console.WriteLine("URL do pagamento : " + paymentRedirectUri);
        Console.ReadKey();
    }
    catch (PagSeguroServiceException exception)
    {
        Console.WriteLine(exception.Message + "\n");
        foreach (var element in exception.Errors)
        {
            Console.WriteLine(element + "\n");
        }
        Console.ReadKey();
    }
Create Order with Signature
Here a signature release is made within a normal sale, which asks the user for approval.
        var now = DateTime.Now;
        payment.PreApproval = new PreApproval
        {
            Charge = Charge.Manual,
            Name = "Seguro contra roubo do Notebook",
            AmountPerPayment = 100.00m,
            MaxAmountPerPeriod = 100.00m,
            Details = string.Format("Todo dia {0} será cobrado o valor de {1} referente ao seguro contra roubo do Notebook.", now.Day, payment.PreApproval.AmountPerPayment.ToString("C2")),
            Period = Period.Monthly,
            DayOfMonth = now.Day,
            InitialDate = now,
            FinalDate = now.AddMonths(6),
            MaxTotalAmount = 600.00m,
            MaxPaymentsPerPeriod = 1
        };
Unsubscribe
    // Tendo um código de transação, insira no segundo argumento.
    var cancelResult = PreApprovalService.CancelPreApproval(credentials, "3DFAD3123412340334A96F9136C38804");
Check Status of a Transaction
    // Transação Normal
    var transaction = NotificationService.CheckTransaction(credentials, "766B9C-AD4B044B04DA-77742F5FA653-E1AB24", false);
    // Transação Tipo Assinatura
    var preApprovalTransaction = NotificationService.CheckTransaction(credentials, "3DFAD3123412340334A96F9136C38804", true);
Search Transaction by Transaction Code
    var preApprovalTransaction = TransactionSearchService.SearchByCode(credentials, "3DFAD3123412340334A96F9136C38804", true);
Search Transactions by Date Range
        // Definindo a data de ínicio da consulta 
        var initialDate = new DateTime(2014, 07, 01, 08, 50, 0);
        // Definindo a data de término da consulta
        var finalDate = DateTime.Now.AddHours(-5);
        // Definindo o número máximo de resultados por página
        const int maxPageResults = 10;
        // Definindo o número da página
        const int pageNumber = 1;
        // Realizando a consulta
        var result =
            TransactionSearchService.SearchByDate(
                credentials,
                initialDate,
                finalDate,
                pageNumber,
                maxPageResults,
                false);
        if (result.Transactions.Count <= 0)
        {
            Console.WriteLine("Nenhuma transação");
        }
        if (result.PreApprovals.Count <= 0)
        {
            Console.WriteLine("Nenhuma assinatura");
        }
        foreach (var transaction in result.Transactions)
        {
            Console.WriteLine("Começando listagem de transações - \n");
            Console.WriteLine(transaction.ToString());
            Console.WriteLine(" - Terminando listagem de transações ");
        }
        foreach (var transaction in result.PreApprovals)
        {
            Console.WriteLine("Começando listagem de assinaturas - \n");
            Console.WriteLine(transaction.ToString());
            Console.WriteLine(" - Terminando listagem de assinaturas ");
        }
							
							
						 
Felipe Insurance Pag advises in their own blog the creation of payments of R $ 1,00 (if I mistake) to be paid with billet! This procedure will already generate a status change in their system that your app can receive and test. The first thing I would advise you to do is to make sure that you are correctly setting up your site’s return url, as this is where you will make all the magic happen, if the address is not well configured on the Secure Pag platform you will not receive the answers to update your system.
– Aluisio Martins Junior